@azure/communication-react 1.16.0-alpha-202404252104 → 1.16.0-alpha-202404270012
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/communication-react.d.ts +12 -1
- package/dist/dist-cjs/communication-react/{ChatMessageComponentAsRichTextEditBox-CWvESa8u.js → ChatMessageComponentAsRichTextEditBox-DSlV4PZz.js} +2 -2
- package/dist/dist-cjs/communication-react/{ChatMessageComponentAsRichTextEditBox-CWvESa8u.js.map → ChatMessageComponentAsRichTextEditBox-DSlV4PZz.js.map} +1 -1
- package/dist/dist-cjs/communication-react/{index-BTXDJhYg.js → index-aGXLnB_I.js} +271 -100
- package/dist/dist-cjs/communication-react/index-aGXLnB_I.js.map +1 -0
- package/dist/dist-cjs/communication-react/index.js +1 -1
- package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js +1 -1
- package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js.map +1 -1
- package/dist/dist-esm/calling-component-bindings/src/captionsSelector.js +1 -1
- package/dist/dist-esm/calling-component-bindings/src/captionsSelector.js.map +1 -1
- package/dist/dist-esm/calling-stateful-client/src/Converter.js +1 -1
- package/dist/dist-esm/calling-stateful-client/src/Converter.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageContent.js +28 -1
- package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageContent.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/DevicesButton.d.ts +2 -1
- package/dist/dist-esm/react-components/src/components/DevicesButton.js +6 -2
- package/dist/dist-esm/react-components/src/components/DevicesButton.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/InputBoxButton.d.ts +1 -0
- package/dist/dist-esm/react-components/src/components/InputBoxButton.js +9 -8
- package/dist/dist-esm/react-components/src/components/InputBoxButton.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/Table/RichTextInsertTableButton.js +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/Table/RichTextInsertTableButton.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/Table/RichTextInsertTablePane.d.ts +1 -2
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/Table/RichTextInsertTablePane.js +4 -2
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/Table/RichTextInsertTablePane.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextSendBox.js +22 -7
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextSendBox.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/SendBox.js +16 -6
- package/dist/dist-esm/react-components/src/components/SendBox.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/utils/SendBoxUtils.d.ts +15 -0
- package/dist/dist-esm/react-components/src/components/utils/SendBoxUtils.js +19 -0
- package/dist/dist-esm/react-components/src/components/utils/SendBoxUtils.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/CallComposite.js +3 -2
- package/dist/dist-esm/react-composites/src/composites/CallComposite/CallComposite.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/CallWithChatComposite.js +3 -1
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/CallWithChatComposite.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/ChatButton/useUnreadMessagesTracker.d.ts +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/ChatButton/useUnreadMessagesTracker.js +3 -3
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/ChatButton/useUnreadMessagesTracker.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/AzureCommunicationCallWithChatAdapter.d.ts +26 -12
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/AzureCommunicationCallWithChatAdapter.js +130 -66
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/AzureCommunicationCallWithChatAdapter.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/CallWithChatAdapter.d.ts +11 -1
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/CallWithChatAdapter.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/index.d.ts +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/index.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/AudioProvider.d.ts +19 -0
- package/dist/dist-esm/react-composites/src/composites/common/AudioProvider.js +25 -0
- package/dist/dist-esm/react-composites/src/composites/common/AudioProvider.js.map +1 -0
- package/dist/dist-esm/react-composites/src/composites/common/BaseComposite.js +7 -1
- package/dist/dist-esm/react-composites/src/composites/common/BaseComposite.js.map +1 -1
- package/package.json +1 -1
- package/dist/dist-cjs/communication-react/index-BTXDJhYg.js.map +0 -1
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"RichTextInsertTablePane.js","sourceRoot":"","sources":["../../../../../../../../../react-components/src/components/RichTextEditor/Buttons/Table/RichTextInsertTablePane.tsx"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE7E,OAAO,EACL,uCAAuC,EACvC,+BAA+B,EAC/B,wBAAwB,EACxB,0BAA0B,EAC3B,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,sBAAsB,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;
|
1
|
+
{"version":3,"file":"RichTextInsertTablePane.js","sourceRoot":"","sources":["../../../../../../../../../react-components/src/components/RichTextEditor/Buttons/Table/RichTextInsertTablePane.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport React, { useMemo } from 'react';\nimport { FocusZone, FocusZoneDirection, mergeStyles } from '@fluentui/react';\nimport type { IContextualMenuItem } from '@fluentui/react';\nimport {\n insertTableMenuCellButtonSelectedStyles,\n insertTableMenuCellButtonStyles,\n insertTableMenuFocusZone,\n insertTableMenuTitleStyles\n} from '../../../styles/RichTextEditor.styles';\nimport { ColumnRowReplaceString, createKey } from '../../../utils/RichTextTableUtils';\nimport { useTheme } from '../../../../theming';\n\n// This file uses RoosterJS React package implementation with updates to UI components and styles.\nconst RowColumnInitialValue = 0;\n\ninterface RichTextInsertTablePaneProps {\n item: IContextualMenuItem;\n onClick: (e: React.MouseEvent<Element> | React.KeyboardEvent<Element>, item: IContextualMenuItem) => void;\n maxRowsNumber: number;\n maxColumnsNumber: number;\n}\n\n/**\n * @private\n * Component for the insert table pane\n */\nexport const RichTextInsertTablePane = (props: RichTextInsertTablePaneProps): JSX.Element => {\n const { item, onClick, maxColumnsNumber, maxRowsNumber } = props;\n const [column, setColumn] = React.useState(RowColumnInitialValue);\n const [row, setRow] = React.useState(RowColumnInitialValue);\n const theme = useTheme();\n\n const updateSize = React.useCallback(\n (target?: HTMLElement) => {\n if (target !== undefined && target.dataset.column !== undefined && target.dataset.row !== undefined) {\n const column = parseInt(target.dataset.column);\n const row = parseInt(target.dataset.row);\n\n if (\n column >= RowColumnInitialValue &&\n column < maxColumnsNumber &&\n row >= RowColumnInitialValue &&\n row < maxRowsNumber\n ) {\n setColumn(column);\n setRow(row);\n }\n }\n },\n [maxColumnsNumber, maxRowsNumber]\n );\n\n const onMouseEnter = React.useCallback(\n (e: React.MouseEvent<HTMLButtonElement>) => {\n updateSize(e.target as HTMLElement);\n },\n [updateSize]\n );\n\n const onClickButton = React.useCallback(\n (e: React.MouseEvent<HTMLButtonElement>) => {\n onClick(e, {\n ...item,\n key: createKey(formatRowColumnText(row), formatRowColumnText(column))\n });\n },\n [row, column, onClick, item]\n );\n\n const items = React.useMemo(() => {\n const items: JSX.Element[] = [];\n\n for (let i = 0; i < maxRowsNumber; i++) {\n for (let j = 0; j < maxColumnsNumber; j++) {\n const key = `cell_${i}_${j}`;\n const isSelected = j <= column && i <= row;\n items.push(\n <button\n className={mergeStyles(\n insertTableMenuCellButtonStyles(theme),\n isSelected ? insertTableMenuCellButtonSelectedStyles(theme) : undefined\n )}\n onClick={onClickButton}\n key={key}\n id={key}\n data-column={j}\n data-row={i}\n data-is-focusable={true}\n onMouseEnter={onMouseEnter}\n aria-label={formatText(item.text ?? '', formatRowColumnText(i), formatRowColumnText(j))}\n data-testid={key}\n />\n );\n }\n }\n\n return items;\n }, [maxRowsNumber, maxColumnsNumber, column, row, theme, onClickButton, onMouseEnter, item.text]);\n\n const text = useMemo(() => {\n return formatText(item.text ?? '', formatRowColumnText(row), formatRowColumnText(column));\n }, [column, item.text, row]);\n\n return (\n <div>\n <div className={insertTableMenuTitleStyles}>{text}</div>\n <FocusZone\n defaultTabbableElement={`cell_${RowColumnInitialValue}_${RowColumnInitialValue}`}\n direction={FocusZoneDirection.bidirectional}\n onActiveElementChanged={updateSize}\n className={insertTableMenuFocusZone(theme)}\n >\n {items}\n </FocusZone>\n </div>\n );\n};\n\nconst formatText = (text: string, row: number, column: number): string => {\n return text.replace(`${ColumnRowReplaceString}`, `${column.toString()} x ${row.toString()}`);\n};\n\nconst formatRowColumnText = (value: number): number => {\n return value + 1;\n};\n"]}
|
@@ -7,7 +7,7 @@ import { useLocale } from '../../localization';
|
|
7
7
|
import { sendIconStyle } from '../styles/SendBox.styles';
|
8
8
|
import { InputBoxButton } from '../InputBoxButton';
|
9
9
|
import { RichTextSendBoxErrors } from './RichTextSendBoxErrors';
|
10
|
-
import { isMessageTooLong, sanitizeText } from '../utils/SendBoxUtils';
|
10
|
+
import { isMessageTooLong, isSendBoxButtonAriaDisabled, sanitizeText } from '../utils/SendBoxUtils';
|
11
11
|
import { useTheme } from '../../theming';
|
12
12
|
import { richTextActionButtonsStyle, sendBoxRichTextEditorStyle } from '../styles/RichTextEditor.styles';
|
13
13
|
/* @conditional-compile-remove(attachment-upload) */
|
@@ -81,8 +81,8 @@ export const RichTextSendBox = (props) => {
|
|
81
81
|
onSendMessage(message);
|
82
82
|
setContentValue('');
|
83
83
|
(_b = editorComponentRef.current) === null || _b === void 0 ? void 0 : _b.setEmptyContent();
|
84
|
+
(_c = editorComponentRef.current) === null || _c === void 0 ? void 0 : _c.focus();
|
84
85
|
}
|
85
|
-
(_c = editorComponentRef.current) === null || _c === void 0 ? void 0 : _c.focus();
|
86
86
|
}, [
|
87
87
|
contentValue,
|
88
88
|
contentValueOverflow,
|
@@ -108,16 +108,18 @@ export const RichTextSendBox = (props) => {
|
|
108
108
|
attachmentUploadsPendingError,
|
109
109
|
systemMessage
|
110
110
|
]);
|
111
|
-
const
|
111
|
+
const hasContent = useMemo(() => {
|
112
112
|
var _a;
|
113
113
|
// get plain text content from the editor to check if the message is empty
|
114
114
|
// as the content may contain tags even when the content is empty
|
115
115
|
const plainTextContent = (_a = editorComponentRef.current) === null || _a === void 0 ? void 0 : _a.getPlainContent();
|
116
|
-
|
116
|
+
return !isContentEmpty({
|
117
117
|
plainTextContent: plainTextContent,
|
118
118
|
content: contentValue,
|
119
119
|
placeholder: strings.placeholderText
|
120
120
|
});
|
121
|
+
}, [contentValue, strings.placeholderText]);
|
122
|
+
const onRenderSendIcon = useCallback((isHover) => {
|
121
123
|
return (React.createElement(Icon, { iconName: isHover && hasContent ? 'SendBoxSendHovered' : 'SendBoxSend', className: sendIconStyle({
|
122
124
|
theme,
|
123
125
|
hasText: hasContent,
|
@@ -127,7 +129,7 @@ export const RichTextSendBox = (props) => {
|
|
127
129
|
defaultTextColor: theme.palette.neutralSecondary,
|
128
130
|
disabled: disabled
|
129
131
|
}) }));
|
130
|
-
}, [
|
132
|
+
}, [disabled, hasContent, hasErrorMessage, theme]);
|
131
133
|
const sendBoxErrorsProps = useMemo(() => {
|
132
134
|
var _a, _b;
|
133
135
|
/* @conditional-compile-remove(attachment-upload) */
|
@@ -172,12 +174,25 @@ export const RichTextSendBox = (props) => {
|
|
172
174
|
strings.attachmentMoreMenu,
|
173
175
|
theme
|
174
176
|
]);
|
177
|
+
const isSendBoxButtonAriaDisabledValue = useMemo(() => {
|
178
|
+
return isSendBoxButtonAriaDisabled({
|
179
|
+
hasContent,
|
180
|
+
/* @conditional-compile-remove(attachment-upload) */ hasCompletedAttachmentUploads: hasCompletedAttachmentUploads(attachmentsWithProgress),
|
181
|
+
hasError: hasErrorMessage,
|
182
|
+
disabled
|
183
|
+
});
|
184
|
+
}, [
|
185
|
+
/* @conditional-compile-remove(attachment-upload) */ attachmentsWithProgress,
|
186
|
+
disabled,
|
187
|
+
hasContent,
|
188
|
+
hasErrorMessage
|
189
|
+
]);
|
175
190
|
const sendButton = useMemo(() => {
|
176
191
|
return (React.createElement(InputBoxButton, { onRenderIcon: onRenderSendIcon, onClick: (e) => {
|
177
192
|
sendMessageOnClick();
|
178
193
|
e.stopPropagation(); // Prevents the click from bubbling up and triggering a focus event on the chat.
|
179
|
-
}, className: richTextActionButtonsStyle, ariaLabel: localeStrings.sendButtonAriaLabel, tooltipContent: localeStrings.sendButtonAriaLabel }));
|
180
|
-
}, [localeStrings.sendButtonAriaLabel, onRenderSendIcon, sendMessageOnClick]);
|
194
|
+
}, className: richTextActionButtonsStyle, ariaLabel: localeStrings.sendButtonAriaLabel, tooltipContent: localeStrings.sendButtonAriaLabel, ariaDisabled: isSendBoxButtonAriaDisabledValue }));
|
195
|
+
}, [isSendBoxButtonAriaDisabledValue, localeStrings.sendButtonAriaLabel, onRenderSendIcon, sendMessageOnClick]);
|
181
196
|
/* @conditional-compile-remove(attachment-upload) */
|
182
197
|
const hasAttachmentUploads = useMemo(() => {
|
183
198
|
return (hasCompletedAttachmentUploads(attachmentsWithProgress) || hasIncompleteAttachmentUploads(attachmentsWithProgress));
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"RichTextSendBox.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/RichTextEditor/RichTextSendBox.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport React, { useCallback, useMemo, useRef, useState } from 'react';\nimport { RichTextInputBoxComponent } from './RichTextInputBoxComponent';\nimport { Icon, Stack } from '@fluentui/react';\nimport { useLocale } from '../../localization';\nimport { SendBoxStrings } from '../SendBox';\nimport { sendIconStyle } from '../styles/SendBox.styles';\nimport { InputBoxButton } from '../InputBoxButton';\nimport { RichTextSendBoxErrors, RichTextSendBoxErrorsProps } from './RichTextSendBoxErrors';\nimport { isMessageTooLong, sanitizeText } from '../utils/SendBoxUtils';\nimport { RichTextEditorComponentRef } from './RichTextEditor';\nimport { useTheme } from '../../theming';\nimport { richTextActionButtonsStyle, sendBoxRichTextEditorStyle } from '../styles/RichTextEditor.styles';\n/* @conditional-compile-remove(attachment-upload) */\nimport { _AttachmentUploadCards } from '../AttachmentUploadCards';\n/* @conditional-compile-remove(attachment-upload) */\nimport { AttachmentMetadataWithProgress } from '../../types/Attachment';\n/* @conditional-compile-remove(attachment-upload) */\nimport { hasCompletedAttachmentUploads, hasIncompleteAttachmentUploads } from '../utils/SendBoxUtils';\n/* @conditional-compile-remove(attachment-upload) */\nimport { SendBoxErrorBarError } from '../SendBoxErrorBar';\n/* @conditional-compile-remove(attachment-upload) */\nimport { attachmentUploadCardsStyles } from '../styles/SendBox.styles';\n/* @conditional-compile-remove(attachment-upload) */\nimport { FluentV9ThemeProvider } from '../../theming/FluentV9ThemeProvider';\n\n/**\n * Strings of {@link RichTextSendBox} that can be overridden.\n *\n * @beta\n */\nexport interface RichTextSendBoxStrings extends SendBoxStrings {\n /**\n * Tooltip text for the bold button.\n */\n boldTooltip: string;\n /**\n * Tooltip text for the italic button.\n */\n italicTooltip: string;\n /**\n * Tooltip text for the underline button.\n */\n underlineTooltip: string;\n /**\n * Tooltip text for the bullet list button.\n */\n bulletListTooltip: string;\n /**\n * Tooltip text for the number list button.\n */\n numberListTooltip: string;\n /**\n * Tooltip text for the increase indent button.\n */\n increaseIndentTooltip: string;\n /**\n * Tooltip text for the decrease indent button.\n */\n decreaseIndentTooltip: string;\n /**\n * Tooltip text insert table button.\n */\n insertTableTooltip: string;\n /**\n * Tooltip text for the rich text format button button.\n */\n richTextFormatButtonTooltip: string;\n /**\n * Text for the insert menu item.\n */\n insertRowOrColumnMenu: string;\n /**\n * Title for the insert table menu.\n */\n insertTableMenuTitle: string;\n /**\n * Text for the insert menu item to insert row above the current selection.\n */\n insertRowAboveMenu: string;\n /**\n * Text for the insert menu item to insert row below the current selection.\n */\n insertRowBelowMenu: string;\n /**\n * Text for the insert menu item to insert column to the left from the current selection.\n */\n insertColumnLeftMenu: string;\n /**\n * Text for the insert menu item to insert column to the right from the current selection.\n */\n insertColumnRightMenu: string;\n /**\n * Text for the delete row or column menu.\n */\n deleteRowOrColumnMenu: string;\n /**\n * Text for the delete column menu.\n */\n deleteColumnMenu: string;\n /**\n * Text for the delete row menu.\n */\n deleteRowMenu: string;\n /**\n * Text for the delete table menu.\n */\n deleteTableMenu: string;\n}\n\n/**\n * Props for {@link RichTextSendBox}.\n *\n * @beta\n */\nexport interface RichTextSendBoxProps {\n /**\n * Optional boolean to disable text box\n * @defaultValue false\n */\n disabled?: boolean;\n /**\n * Optional strings to override in component\n */\n strings?: Partial<RichTextSendBoxStrings>;\n /**\n * Optional text for system message above the text box\n */\n systemMessage?: string;\n /* @conditional-compile-remove(attachment-upload) */\n /**\n * Optional array of type {@link AttachmentMetadataWithProgress}\n * to render attachments being uploaded in the SendBox.\n * @beta\n */\n attachmentsWithProgress?: AttachmentMetadataWithProgress[];\n /**\n * enumerable to determine if the input box has focus on render or not.\n * When undefined nothing has focus on render\n */\n autoFocus?: 'sendBoxTextField';\n /* @conditional-compile-remove(attachment-upload) */\n /**\n * Optional callback to remove the attachment upload before sending by clicking on\n * cancel icon.\n * @beta\n */\n onCancelAttachmentUpload?: (attachmentId: string) => void;\n /**\n * Callback function used when the send button is clicked.\n */\n onSendMessage: (content: string) => Promise<void>;\n /**\n * Optional callback called when user is typing\n */\n onTyping?: () => Promise<void>;\n}\n\n/**\n * A component to render SendBox with Rich Text Editor support.\n *\n * @beta\n */\nexport const RichTextSendBox = (props: RichTextSendBoxProps): JSX.Element => {\n const {\n disabled = false,\n systemMessage,\n autoFocus,\n onSendMessage,\n onTyping,\n /* @conditional-compile-remove(attachment-upload) */\n attachmentsWithProgress,\n /* @conditional-compile-remove(attachment-upload) */\n onCancelAttachmentUpload\n } = props;\n\n const theme = useTheme();\n const locale = useLocale();\n\n const localeStrings = useMemo(() => {\n /* @conditional-compile-remove(rich-text-editor) */\n return locale.strings.richTextSendBox;\n return locale.strings.sendBox;\n }, [/* @conditional-compile-remove(rich-text-editor) */ locale.strings.richTextSendBox, locale.strings.sendBox]);\n\n const strings = useMemo(() => {\n return { ...localeStrings, ...props.strings };\n }, [localeStrings, props.strings]);\n\n const [contentValue, setContentValue] = useState('');\n const [contentValueOverflow, setContentValueOverflow] = useState(false);\n /* @conditional-compile-remove(attachment-upload) */\n const [attachmentUploadsPendingError, setAttachmentUploadsPendingError] = useState<SendBoxErrorBarError | undefined>(\n undefined\n );\n const editorComponentRef = useRef<RichTextEditorComponentRef>(null);\n\n const contentTooLongMessage = useMemo(\n () => (contentValueOverflow ? strings.textTooLong : undefined),\n [contentValueOverflow, strings.textTooLong]\n );\n\n const setContent = useCallback((newValue?: string): void => {\n if (newValue === undefined) {\n return;\n }\n\n setContentValueOverflow(isMessageTooLong(newValue.length));\n setContentValue(newValue);\n }, []);\n\n const sendMessageOnClick = useCallback((): void => {\n if (disabled || contentValueOverflow) {\n return;\n }\n // Don't send message until all attachments have been uploaded successfully\n /* @conditional-compile-remove(attachment-upload) */\n setAttachmentUploadsPendingError(undefined);\n\n /* @conditional-compile-remove(attachment-upload) */\n if (hasIncompleteAttachmentUploads(attachmentsWithProgress)) {\n setAttachmentUploadsPendingError({ message: strings.attachmentUploadsPendingError, timestamp: Date.now() });\n return;\n }\n\n const message = contentValue;\n // get plain text content from the editor to check if the message is empty\n // as the content may contain tags even when the content is empty\n const plainTextContent = editorComponentRef.current?.getPlainContent();\n const hasContent = !isContentEmpty({\n plainTextContent,\n content: message,\n placeholder: strings.placeholderText\n });\n // we don't want to send empty messages including spaces, newlines, tabs\n // Message can be empty if there is a valid attachment upload\n if (\n hasContent ||\n /* @conditional-compile-remove(attachment-upload) */ hasCompletedAttachmentUploads(attachmentsWithProgress)\n ) {\n onSendMessage(message);\n setContentValue('');\n editorComponentRef.current?.setEmptyContent();\n }\n editorComponentRef.current?.focus();\n }, [\n contentValue,\n contentValueOverflow,\n disabled,\n onSendMessage,\n strings.placeholderText,\n /* @conditional-compile-remove(attachment-upload) */ attachmentsWithProgress,\n /* @conditional-compile-remove(attachment-upload) */ strings.attachmentUploadsPendingError\n ]);\n\n const hasErrorMessage = useMemo(() => {\n return (\n !!systemMessage ||\n !!contentTooLongMessage ||\n /* @conditional-compile-remove(attachment-upload) */\n !!attachmentUploadsPendingError ||\n /* @conditional-compile-remove(attachment-upload) */\n !!attachmentsWithProgress?.filter((attachmentUpload) => attachmentUpload.error).pop()?.error\n );\n }, [\n /* @conditional-compile-remove(attachment-upload) */\n attachmentsWithProgress,\n contentTooLongMessage,\n /* @conditional-compile-remove(attachment-upload) */\n attachmentUploadsPendingError,\n systemMessage\n ]);\n\n const onRenderSendIcon = useCallback(\n (isHover: boolean) => {\n // get plain text content from the editor to check if the message is empty\n // as the content may contain tags even when the content is empty\n const plainTextContent = editorComponentRef.current?.getPlainContent();\n const hasContent = !isContentEmpty({\n plainTextContent: plainTextContent,\n content: contentValue,\n placeholder: strings.placeholderText\n });\n return (\n <Icon\n iconName={isHover && hasContent ? 'SendBoxSendHovered' : 'SendBoxSend'}\n className={sendIconStyle({\n theme,\n hasText: hasContent,\n /* @conditional-compile-remove(attachment-upload) */\n hasAttachment: false,\n hasErrorMessage: hasErrorMessage,\n defaultTextColor: theme.palette.neutralSecondary,\n disabled: disabled\n })}\n />\n );\n },\n [contentValue, disabled, hasErrorMessage, strings.placeholderText, theme]\n );\n\n const sendBoxErrorsProps: RichTextSendBoxErrorsProps = useMemo(() => {\n /* @conditional-compile-remove(attachment-upload) */\n const uploadErrorMessage = attachmentsWithProgress?.filter((attachmentUpload) => attachmentUpload.error).pop()\n ?.error?.message;\n return {\n /* @conditional-compile-remove(attachment-upload) */\n attachmentUploadsPendingError: attachmentUploadsPendingError,\n /* @conditional-compile-remove(attachment-upload) */\n attachmentProgressError: uploadErrorMessage\n ? {\n message: uploadErrorMessage,\n timestamp: Date.now()\n }\n : undefined,\n systemMessage: systemMessage,\n textTooLongMessage: contentTooLongMessage\n };\n }, [\n /* @conditional-compile-remove(attachment-upload) */\n attachmentsWithProgress,\n contentTooLongMessage,\n /* @conditional-compile-remove(attachment-upload) */\n attachmentUploadsPendingError,\n systemMessage\n ]);\n\n /* @conditional-compile-remove(attachment-upload) */\n const onRenderAttachmentUploads = useCallback(() => {\n return (\n <Stack className={attachmentUploadCardsStyles}>\n <FluentV9ThemeProvider v8Theme={theme}>\n <_AttachmentUploadCards\n attachmentsWithProgress={attachmentsWithProgress}\n onCancelAttachmentUpload={onCancelAttachmentUpload}\n strings={{\n removeAttachment: strings.removeAttachment,\n uploading: strings.uploading,\n uploadCompleted: strings.uploadCompleted,\n attachmentMoreMenu: strings.attachmentMoreMenu\n }}\n />\n </FluentV9ThemeProvider>\n </Stack>\n );\n }, [\n attachmentsWithProgress,\n onCancelAttachmentUpload,\n strings.removeAttachment,\n strings.uploadCompleted,\n strings.uploading,\n strings.attachmentMoreMenu,\n theme\n ]);\n\n const sendButton = useMemo(() => {\n return (\n <InputBoxButton\n onRenderIcon={onRenderSendIcon}\n onClick={(e) => {\n sendMessageOnClick();\n e.stopPropagation(); // Prevents the click from bubbling up and triggering a focus event on the chat.\n }}\n className={richTextActionButtonsStyle}\n ariaLabel={localeStrings.sendButtonAriaLabel}\n tooltipContent={localeStrings.sendButtonAriaLabel}\n />\n );\n }, [localeStrings.sendButtonAriaLabel, onRenderSendIcon, sendMessageOnClick]);\n\n /* @conditional-compile-remove(attachment-upload) */\n const hasAttachmentUploads = useMemo(() => {\n return (\n hasCompletedAttachmentUploads(attachmentsWithProgress) || hasIncompleteAttachmentUploads(attachmentsWithProgress)\n );\n }, [attachmentsWithProgress]);\n\n return (\n <Stack>\n <RichTextSendBoxErrors {...sendBoxErrorsProps} />\n <RichTextInputBoxComponent\n // in case when format bar is shown, the editor is re-rendered that causes the content to be lost\n // setting the content will ensure that the latest content is used when editor is re-rendered\n content={contentValue}\n placeholderText={strings.placeholderText}\n autoFocus={autoFocus}\n onChange={setContent}\n onEnterKeyDown={sendMessageOnClick}\n onTyping={onTyping}\n editorComponentRef={editorComponentRef}\n strings={strings}\n disabled={disabled}\n actionComponents={sendButton}\n richTextEditorStyleProps={sendBoxRichTextEditorStyle}\n /* @conditional-compile-remove(attachment-upload) */\n onRenderAttachmentUploads={onRenderAttachmentUploads}\n /* @conditional-compile-remove(attachment-upload) */\n hasAttachments={hasAttachmentUploads}\n />\n </Stack>\n );\n};\n\n/**\n * Checks if the content of the rich text editor is empty.\n *\n * @param {Object} params - The parameters for the function.\n * @param {string | undefined} params.plainTextContent - The plain text content of the editor.\n * @param {string} params.content - The HTML content of the editor.\n * @param {string} params.placeholder - The placeholder text of the editor.\n * @returns {boolean} - True if the content is empty, false otherwise.\n */\nconst isContentEmpty = ({\n plainTextContent,\n content,\n placeholder\n}: {\n plainTextContent: string | undefined;\n content: string;\n placeholder: string;\n}): boolean => {\n // RoosterJS returns placeholder text as plain text when the editor is empty and in this case,\n // plainTextContent contains only placeholder text but content doesn't include the placeholder text\n // this needs to be reviewed after migration to the content model packages.\n const plainTextContainsPlaceholderOnly = plainTextContent === placeholder && !content.includes(placeholder);\n return plainTextContainsPlaceholderOnly || sanitizeText(plainTextContent ?? '').length === 0;\n};\n"]}
|
1
|
+
{"version":3,"file":"RichTextSendBox.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/RichTextEditor/RichTextSendBox.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport React, { useCallback, useMemo, useRef, useState } from 'react';\nimport { RichTextInputBoxComponent } from './RichTextInputBoxComponent';\nimport { Icon, Stack } from '@fluentui/react';\nimport { useLocale } from '../../localization';\nimport { SendBoxStrings } from '../SendBox';\nimport { sendIconStyle } from '../styles/SendBox.styles';\nimport { InputBoxButton } from '../InputBoxButton';\nimport { RichTextSendBoxErrors, RichTextSendBoxErrorsProps } from './RichTextSendBoxErrors';\nimport { isMessageTooLong, isSendBoxButtonAriaDisabled, sanitizeText } from '../utils/SendBoxUtils';\nimport { RichTextEditorComponentRef } from './RichTextEditor';\nimport { useTheme } from '../../theming';\nimport { richTextActionButtonsStyle, sendBoxRichTextEditorStyle } from '../styles/RichTextEditor.styles';\n/* @conditional-compile-remove(attachment-upload) */\nimport { _AttachmentUploadCards } from '../AttachmentUploadCards';\n/* @conditional-compile-remove(attachment-upload) */\nimport { AttachmentMetadataWithProgress } from '../../types/Attachment';\n/* @conditional-compile-remove(attachment-upload) */\nimport { hasCompletedAttachmentUploads, hasIncompleteAttachmentUploads } from '../utils/SendBoxUtils';\n/* @conditional-compile-remove(attachment-upload) */\nimport { SendBoxErrorBarError } from '../SendBoxErrorBar';\n/* @conditional-compile-remove(attachment-upload) */\nimport { attachmentUploadCardsStyles } from '../styles/SendBox.styles';\n/* @conditional-compile-remove(attachment-upload) */\nimport { FluentV9ThemeProvider } from '../../theming/FluentV9ThemeProvider';\n\n/**\n * Strings of {@link RichTextSendBox} that can be overridden.\n *\n * @beta\n */\nexport interface RichTextSendBoxStrings extends SendBoxStrings {\n /**\n * Tooltip text for the bold button.\n */\n boldTooltip: string;\n /**\n * Tooltip text for the italic button.\n */\n italicTooltip: string;\n /**\n * Tooltip text for the underline button.\n */\n underlineTooltip: string;\n /**\n * Tooltip text for the bullet list button.\n */\n bulletListTooltip: string;\n /**\n * Tooltip text for the number list button.\n */\n numberListTooltip: string;\n /**\n * Tooltip text for the increase indent button.\n */\n increaseIndentTooltip: string;\n /**\n * Tooltip text for the decrease indent button.\n */\n decreaseIndentTooltip: string;\n /**\n * Tooltip text insert table button.\n */\n insertTableTooltip: string;\n /**\n * Tooltip text for the rich text format button button.\n */\n richTextFormatButtonTooltip: string;\n /**\n * Text for the insert menu item.\n */\n insertRowOrColumnMenu: string;\n /**\n * Title for the insert table menu.\n */\n insertTableMenuTitle: string;\n /**\n * Text for the insert menu item to insert row above the current selection.\n */\n insertRowAboveMenu: string;\n /**\n * Text for the insert menu item to insert row below the current selection.\n */\n insertRowBelowMenu: string;\n /**\n * Text for the insert menu item to insert column to the left from the current selection.\n */\n insertColumnLeftMenu: string;\n /**\n * Text for the insert menu item to insert column to the right from the current selection.\n */\n insertColumnRightMenu: string;\n /**\n * Text for the delete row or column menu.\n */\n deleteRowOrColumnMenu: string;\n /**\n * Text for the delete column menu.\n */\n deleteColumnMenu: string;\n /**\n * Text for the delete row menu.\n */\n deleteRowMenu: string;\n /**\n * Text for the delete table menu.\n */\n deleteTableMenu: string;\n}\n\n/**\n * Props for {@link RichTextSendBox}.\n *\n * @beta\n */\nexport interface RichTextSendBoxProps {\n /**\n * Optional boolean to disable text box\n * @defaultValue false\n */\n disabled?: boolean;\n /**\n * Optional strings to override in component\n */\n strings?: Partial<RichTextSendBoxStrings>;\n /**\n * Optional text for system message above the text box\n */\n systemMessage?: string;\n /* @conditional-compile-remove(attachment-upload) */\n /**\n * Optional array of type {@link AttachmentMetadataWithProgress}\n * to render attachments being uploaded in the SendBox.\n * @beta\n */\n attachmentsWithProgress?: AttachmentMetadataWithProgress[];\n /**\n * enumerable to determine if the input box has focus on render or not.\n * When undefined nothing has focus on render\n */\n autoFocus?: 'sendBoxTextField';\n /* @conditional-compile-remove(attachment-upload) */\n /**\n * Optional callback to remove the attachment upload before sending by clicking on\n * cancel icon.\n * @beta\n */\n onCancelAttachmentUpload?: (attachmentId: string) => void;\n /**\n * Callback function used when the send button is clicked.\n */\n onSendMessage: (content: string) => Promise<void>;\n /**\n * Optional callback called when user is typing\n */\n onTyping?: () => Promise<void>;\n}\n\n/**\n * A component to render SendBox with Rich Text Editor support.\n *\n * @beta\n */\nexport const RichTextSendBox = (props: RichTextSendBoxProps): JSX.Element => {\n const {\n disabled = false,\n systemMessage,\n autoFocus,\n onSendMessage,\n onTyping,\n /* @conditional-compile-remove(attachment-upload) */\n attachmentsWithProgress,\n /* @conditional-compile-remove(attachment-upload) */\n onCancelAttachmentUpload\n } = props;\n\n const theme = useTheme();\n const locale = useLocale();\n\n const localeStrings = useMemo(() => {\n /* @conditional-compile-remove(rich-text-editor) */\n return locale.strings.richTextSendBox;\n return locale.strings.sendBox;\n }, [/* @conditional-compile-remove(rich-text-editor) */ locale.strings.richTextSendBox, locale.strings.sendBox]);\n\n const strings = useMemo(() => {\n return { ...localeStrings, ...props.strings };\n }, [localeStrings, props.strings]);\n\n const [contentValue, setContentValue] = useState('');\n const [contentValueOverflow, setContentValueOverflow] = useState(false);\n /* @conditional-compile-remove(attachment-upload) */\n const [attachmentUploadsPendingError, setAttachmentUploadsPendingError] = useState<SendBoxErrorBarError | undefined>(\n undefined\n );\n const editorComponentRef = useRef<RichTextEditorComponentRef>(null);\n\n const contentTooLongMessage = useMemo(\n () => (contentValueOverflow ? strings.textTooLong : undefined),\n [contentValueOverflow, strings.textTooLong]\n );\n\n const setContent = useCallback((newValue?: string): void => {\n if (newValue === undefined) {\n return;\n }\n\n setContentValueOverflow(isMessageTooLong(newValue.length));\n setContentValue(newValue);\n }, []);\n\n const sendMessageOnClick = useCallback((): void => {\n if (disabled || contentValueOverflow) {\n return;\n }\n // Don't send message until all attachments have been uploaded successfully\n /* @conditional-compile-remove(attachment-upload) */\n setAttachmentUploadsPendingError(undefined);\n\n /* @conditional-compile-remove(attachment-upload) */\n if (hasIncompleteAttachmentUploads(attachmentsWithProgress)) {\n setAttachmentUploadsPendingError({ message: strings.attachmentUploadsPendingError, timestamp: Date.now() });\n return;\n }\n\n const message = contentValue;\n // get plain text content from the editor to check if the message is empty\n // as the content may contain tags even when the content is empty\n const plainTextContent = editorComponentRef.current?.getPlainContent();\n const hasContent = !isContentEmpty({\n plainTextContent,\n content: message,\n placeholder: strings.placeholderText\n });\n // we don't want to send empty messages including spaces, newlines, tabs\n // Message can be empty if there is a valid attachment upload\n if (\n hasContent ||\n /* @conditional-compile-remove(attachment-upload) */ hasCompletedAttachmentUploads(attachmentsWithProgress)\n ) {\n onSendMessage(message);\n setContentValue('');\n editorComponentRef.current?.setEmptyContent();\n editorComponentRef.current?.focus();\n }\n }, [\n contentValue,\n contentValueOverflow,\n disabled,\n onSendMessage,\n strings.placeholderText,\n /* @conditional-compile-remove(attachment-upload) */ attachmentsWithProgress,\n /* @conditional-compile-remove(attachment-upload) */ strings.attachmentUploadsPendingError\n ]);\n\n const hasErrorMessage = useMemo(() => {\n return (\n !!systemMessage ||\n !!contentTooLongMessage ||\n /* @conditional-compile-remove(attachment-upload) */\n !!attachmentUploadsPendingError ||\n /* @conditional-compile-remove(attachment-upload) */\n !!attachmentsWithProgress?.filter((attachmentUpload) => attachmentUpload.error).pop()?.error\n );\n }, [\n /* @conditional-compile-remove(attachment-upload) */\n attachmentsWithProgress,\n contentTooLongMessage,\n /* @conditional-compile-remove(attachment-upload) */\n attachmentUploadsPendingError,\n systemMessage\n ]);\n\n const hasContent = useMemo(() => {\n // get plain text content from the editor to check if the message is empty\n // as the content may contain tags even when the content is empty\n const plainTextContent = editorComponentRef.current?.getPlainContent();\n return !isContentEmpty({\n plainTextContent: plainTextContent,\n content: contentValue,\n placeholder: strings.placeholderText\n });\n }, [contentValue, strings.placeholderText]);\n\n const onRenderSendIcon = useCallback(\n (isHover: boolean) => {\n return (\n <Icon\n iconName={isHover && hasContent ? 'SendBoxSendHovered' : 'SendBoxSend'}\n className={sendIconStyle({\n theme,\n hasText: hasContent,\n /* @conditional-compile-remove(attachment-upload) */\n hasAttachment: false,\n hasErrorMessage: hasErrorMessage,\n defaultTextColor: theme.palette.neutralSecondary,\n disabled: disabled\n })}\n />\n );\n },\n [disabled, hasContent, hasErrorMessage, theme]\n );\n\n const sendBoxErrorsProps: RichTextSendBoxErrorsProps = useMemo(() => {\n /* @conditional-compile-remove(attachment-upload) */\n const uploadErrorMessage = attachmentsWithProgress?.filter((attachmentUpload) => attachmentUpload.error).pop()\n ?.error?.message;\n return {\n /* @conditional-compile-remove(attachment-upload) */\n attachmentUploadsPendingError: attachmentUploadsPendingError,\n /* @conditional-compile-remove(attachment-upload) */\n attachmentProgressError: uploadErrorMessage\n ? {\n message: uploadErrorMessage,\n timestamp: Date.now()\n }\n : undefined,\n systemMessage: systemMessage,\n textTooLongMessage: contentTooLongMessage\n };\n }, [\n /* @conditional-compile-remove(attachment-upload) */\n attachmentsWithProgress,\n contentTooLongMessage,\n /* @conditional-compile-remove(attachment-upload) */\n attachmentUploadsPendingError,\n systemMessage\n ]);\n\n /* @conditional-compile-remove(attachment-upload) */\n const onRenderAttachmentUploads = useCallback(() => {\n return (\n <Stack className={attachmentUploadCardsStyles}>\n <FluentV9ThemeProvider v8Theme={theme}>\n <_AttachmentUploadCards\n attachmentsWithProgress={attachmentsWithProgress}\n onCancelAttachmentUpload={onCancelAttachmentUpload}\n strings={{\n removeAttachment: strings.removeAttachment,\n uploading: strings.uploading,\n uploadCompleted: strings.uploadCompleted,\n attachmentMoreMenu: strings.attachmentMoreMenu\n }}\n />\n </FluentV9ThemeProvider>\n </Stack>\n );\n }, [\n attachmentsWithProgress,\n onCancelAttachmentUpload,\n strings.removeAttachment,\n strings.uploadCompleted,\n strings.uploading,\n strings.attachmentMoreMenu,\n theme\n ]);\n\n const isSendBoxButtonAriaDisabledValue = useMemo(() => {\n return isSendBoxButtonAriaDisabled({\n hasContent,\n /* @conditional-compile-remove(attachment-upload) */ hasCompletedAttachmentUploads:\n hasCompletedAttachmentUploads(attachmentsWithProgress),\n hasError: hasErrorMessage,\n disabled\n });\n }, [\n /* @conditional-compile-remove(attachment-upload) */ attachmentsWithProgress,\n disabled,\n hasContent,\n hasErrorMessage\n ]);\n\n const sendButton = useMemo(() => {\n return (\n <InputBoxButton\n onRenderIcon={onRenderSendIcon}\n onClick={(e) => {\n sendMessageOnClick();\n e.stopPropagation(); // Prevents the click from bubbling up and triggering a focus event on the chat.\n }}\n className={richTextActionButtonsStyle}\n ariaLabel={localeStrings.sendButtonAriaLabel}\n tooltipContent={localeStrings.sendButtonAriaLabel}\n ariaDisabled={isSendBoxButtonAriaDisabledValue}\n />\n );\n }, [isSendBoxButtonAriaDisabledValue, localeStrings.sendButtonAriaLabel, onRenderSendIcon, sendMessageOnClick]);\n\n /* @conditional-compile-remove(attachment-upload) */\n const hasAttachmentUploads = useMemo(() => {\n return (\n hasCompletedAttachmentUploads(attachmentsWithProgress) || hasIncompleteAttachmentUploads(attachmentsWithProgress)\n );\n }, [attachmentsWithProgress]);\n\n return (\n <Stack>\n <RichTextSendBoxErrors {...sendBoxErrorsProps} />\n <RichTextInputBoxComponent\n // in case when format bar is shown, the editor is re-rendered that causes the content to be lost\n // setting the content will ensure that the latest content is used when editor is re-rendered\n content={contentValue}\n placeholderText={strings.placeholderText}\n autoFocus={autoFocus}\n onChange={setContent}\n onEnterKeyDown={sendMessageOnClick}\n onTyping={onTyping}\n editorComponentRef={editorComponentRef}\n strings={strings}\n disabled={disabled}\n actionComponents={sendButton}\n richTextEditorStyleProps={sendBoxRichTextEditorStyle}\n /* @conditional-compile-remove(attachment-upload) */\n onRenderAttachmentUploads={onRenderAttachmentUploads}\n /* @conditional-compile-remove(attachment-upload) */\n hasAttachments={hasAttachmentUploads}\n />\n </Stack>\n );\n};\n\n/**\n * Checks if the content of the rich text editor is empty.\n *\n * @param {Object} params - The parameters for the function.\n * @param {string | undefined} params.plainTextContent - The plain text content of the editor.\n * @param {string} params.content - The HTML content of the editor.\n * @param {string} params.placeholder - The placeholder text of the editor.\n * @returns {boolean} - True if the content is empty, false otherwise.\n */\nconst isContentEmpty = ({\n plainTextContent,\n content,\n placeholder\n}: {\n plainTextContent: string | undefined;\n content: string;\n placeholder: string;\n}): boolean => {\n // RoosterJS returns placeholder text as plain text when the editor is empty and in this case,\n // plainTextContent contains only placeholder text but content doesn't include the placeholder text\n // this needs to be reviewed after migration to the content model packages.\n const plainTextContainsPlaceholderOnly = plainTextContent === placeholder && !content.includes(placeholder);\n return plainTextContainsPlaceholderOnly || sanitizeText(plainTextContent ?? '').length === 0;\n};\n"]}
|
@@ -16,7 +16,7 @@ import { _AttachmentUploadCards } from './AttachmentUploadCards';
|
|
16
16
|
import { attachmentUploadCardsStyles } from './styles/SendBox.styles';
|
17
17
|
/* @conditional-compile-remove(attachment-upload) */
|
18
18
|
import { hasCompletedAttachmentUploads, hasIncompleteAttachmentUploads } from './utils/SendBoxUtils';
|
19
|
-
import { MAXIMUM_LENGTH_OF_MESSAGE, isMessageTooLong, sanitizeText } from './utils/SendBoxUtils';
|
19
|
+
import { MAXIMUM_LENGTH_OF_MESSAGE, isMessageTooLong, sanitizeText, isSendBoxButtonAriaDisabled } from './utils/SendBoxUtils';
|
20
20
|
/* @conditional-compile-remove(attachment-upload) */
|
21
21
|
import { FluentV9ThemeProvider } from '../theming/FluentV9ThemeProvider';
|
22
22
|
/**
|
@@ -63,8 +63,8 @@ export const SendBox = (props) => {
|
|
63
63
|
/* @conditional-compile-remove(attachment-upload) */ hasCompletedAttachmentUploads(attachmentsWithProgress)) {
|
64
64
|
onSendMessage && onSendMessage(message);
|
65
65
|
setTextValue('');
|
66
|
+
(_a = sendTextFieldRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
66
67
|
}
|
67
|
-
(_a = sendTextFieldRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
68
68
|
};
|
69
69
|
const setText = (newValue) => {
|
70
70
|
if (newValue === undefined) {
|
@@ -79,17 +79,27 @@ export const SendBox = (props) => {
|
|
79
79
|
const mergedStyles = useMemo(() => concatStyleSets(styles), [styles]);
|
80
80
|
const mergedSendIconStyle = useMemo(() => sendIconStyle({
|
81
81
|
theme,
|
82
|
-
hasText:
|
82
|
+
hasText: sanitizeText(textValue).length > 0,
|
83
83
|
/* @conditional-compile-remove(attachment-upload) */ hasAttachment: hasCompletedAttachmentUploads(attachmentsWithProgress),
|
84
84
|
hasErrorMessage: !!errorMessage,
|
85
|
-
customSendIconStyle: styles === null || styles === void 0 ? void 0 : styles.sendMessageIcon
|
85
|
+
customSendIconStyle: styles === null || styles === void 0 ? void 0 : styles.sendMessageIcon,
|
86
|
+
disabled: !!disabled
|
86
87
|
}), [
|
87
88
|
theme,
|
88
89
|
textValue,
|
89
90
|
/* @conditional-compile-remove(attachment-upload) */ attachmentsWithProgress,
|
90
91
|
errorMessage,
|
91
|
-
styles === null || styles === void 0 ? void 0 : styles.sendMessageIcon
|
92
|
+
styles === null || styles === void 0 ? void 0 : styles.sendMessageIcon,
|
93
|
+
disabled
|
92
94
|
]);
|
95
|
+
const isSendBoxButtonAriaDisabledValue = useMemo(() => {
|
96
|
+
return isSendBoxButtonAriaDisabled({
|
97
|
+
hasContent: sanitizeText(textValue).length > 0,
|
98
|
+
/* @conditional-compile-remove(attachment-upload) */ hasCompletedAttachmentUploads: hasCompletedAttachmentUploads(attachmentsWithProgress),
|
99
|
+
hasError: !!errorMessage,
|
100
|
+
disabled: !!disabled
|
101
|
+
});
|
102
|
+
}, [/* @conditional-compile-remove(attachment-upload) */ attachmentsWithProgress, disabled, errorMessage, textValue]);
|
93
103
|
const onRenderSendIcon = useCallback((isHover) => onRenderIcon ? (onRenderIcon(isHover)) : (React.createElement(Icon, { iconName: isHover && textValue ? 'SendBoxSendHovered' : 'SendBoxSend', className: mergedSendIconStyle })), [mergedSendIconStyle, onRenderIcon, textValue]);
|
94
104
|
// Ensure that errors are cleared when there are no attachments in sendBox
|
95
105
|
/* @conditional-compile-remove(attachment-upload) */
|
@@ -158,7 +168,7 @@ export const SendBox = (props) => {
|
|
158
168
|
sendMessageOnClick();
|
159
169
|
}
|
160
170
|
e.stopPropagation();
|
161
|
-
}, id: 'sendIconWrapper', className: mergedSendButtonStyle, ariaLabel: localeStrings.sendButtonAriaLabel, tooltipContent: localeStrings.sendButtonAriaLabel })),
|
171
|
+
}, id: 'sendIconWrapper', className: mergedSendButtonStyle, ariaLabel: localeStrings.sendButtonAriaLabel, tooltipContent: localeStrings.sendButtonAriaLabel, ariaDisabled: isSendBoxButtonAriaDisabledValue })),
|
162
172
|
/* @conditional-compile-remove(attachment-upload) */
|
163
173
|
onRenderAttachmentUploads())));
|
164
174
|
};
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"SendBox.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/SendBox.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport React, { useState, useMemo, useCallback } from 'react';\nimport { IStyle, ITextField, mergeStyles, concatStyleSets, Icon, Stack } from '@fluentui/react';\nimport { sendButtonStyle, sendIconStyle, sendBoxWrapperStyles, borderAndBoxShadowStyle } from './styles/SendBox.styles';\nimport { BaseCustomStyles } from '../types';\nimport { useTheme } from '../theming';\nimport { useLocale } from '../localization';\nimport { useIdentifiers } from '../identifiers';\nimport { InputBoxComponent } from './InputBoxComponent';\nimport { InputBoxButton } from './InputBoxButton';\n/* @conditional-compile-remove(attachment-upload) */\nimport { SendBoxErrors } from './SendBoxErrors';\n/* @conditional-compile-remove(attachment-upload) */\nimport { _AttachmentUploadCards } from './AttachmentUploadCards';\n/* @conditional-compile-remove(attachment-upload) */\nimport { AttachmentMetadataWithProgress } from '../types/Attachment';\n/* @conditional-compile-remove(attachment-upload) */\nimport { attachmentUploadCardsStyles } from './styles/SendBox.styles';\n/* @conditional-compile-remove(attachment-upload) */\nimport { SendBoxErrorBarError } from './SendBoxErrorBar';\n/* @conditional-compile-remove(attachment-upload) */\nimport { hasCompletedAttachmentUploads, hasIncompleteAttachmentUploads } from './utils/SendBoxUtils';\nimport { MAXIMUM_LENGTH_OF_MESSAGE, isMessageTooLong, sanitizeText } from './utils/SendBoxUtils';\n/* @conditional-compile-remove(mention) */\nimport { MentionLookupOptions } from './MentionPopover';\n/* @conditional-compile-remove(attachment-upload) */\nimport { FluentV9ThemeProvider } from '../theming/FluentV9ThemeProvider';\n\n/**\n * Fluent styles for {@link Sendbox}.\n *\n * @public\n */\nexport interface SendBoxStylesProps extends BaseCustomStyles {\n /** Styles for the text field. */\n textField?: IStyle;\n /** styles for the text field container */\n textFieldContainer?: IStyle;\n /** Styles for the container of the send message icon. */\n sendMessageIconContainer?: IStyle;\n /** Styles for the send message icon; These styles will be ignored when a custom send message icon is provided. */\n sendMessageIcon?: IStyle;\n /** Styles for the system message; These styles will be ignored when a custom system message component is provided. */\n systemMessage?: IStyle;\n}\n\n/**\n * Strings of {@link SendBox} that can be overridden.\n *\n * @public\n */\nexport interface SendBoxStrings {\n /**\n * Placeholder text in SendBox when there is no user input\n */\n placeholderText: string;\n /**\n * The warning message when send box text length is more than max limit\n */\n textTooLong: string;\n /**\n * Aria label for send message button\n */\n sendButtonAriaLabel: string;\n /* @conditional-compile-remove(attachment-upload) */\n /**\n * Error message indicating that all attachment uploads are not complete.\n */\n attachmentUploadsPendingError: string;\n /* @conditional-compile-remove(attachment-upload) */\n /**\n * Aria label to notify user when focus is on cancel attachment upload button.\n */\n removeAttachment: string;\n /* @conditional-compile-remove(attachment-upload) */\n /**\n * Aria label to notify user attachment uploading starts.\n */\n uploading: string;\n /* @conditional-compile-remove(attachment-upload) */\n /**\n * Aria label to notify user attachment is uploaded.\n */\n uploadCompleted: string;\n /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */\n /**\n * Aria label to notify user more attachment action menu.\n */\n attachmentMoreMenu: string;\n}\n\n/**\n * Props for {@link SendBox}.\n *\n * @public\n */\nexport interface SendBoxProps {\n /**\n * Optional boolean to disable text box\n * @defaultValue false\n */\n disabled?: boolean;\n /**\n * Optional text for system message below text box\n */\n systemMessage?: string;\n /**\n * Optional override behavior on send button click\n */\n onSendMessage?: (content: string) => Promise<void>;\n /* @conditional-compile-remove(mention) */\n /**\n * Optional props needed to lookup suggestions in the mention scenario.\n * @beta\n */\n mentionLookupOptions?: MentionLookupOptions;\n\n /**\n * Optional callback called when user is typing\n */\n onTyping?: () => Promise<void>;\n /**\n * Optional callback to render system message below the SendBox.\n * @defaultValue MessageBar\n */\n onRenderSystemMessage?: (systemMessage: string | undefined) => React.ReactElement;\n /**\n * Optional boolean to support new line in SendBox.\n * @defaultValue false\n */\n supportNewline?: boolean;\n /**\n * Optional callback to render send button icon to the right of the SendBox.\n * @defaultValue SendBoxSendHovered icon when mouse over icon and SendBoxSend icon otherwise\n */\n onRenderIcon?: (isHover: boolean) => JSX.Element;\n /**\n * Allows users to pass in an object contains custom CSS styles.\n * @Example\n * ```\n * <SendBox styles={{ root: { background: 'blue' } }} />\n * ```\n */\n styles?: SendBoxStylesProps;\n /**\n * Optional strings to override in component\n */\n strings?: Partial<SendBoxStrings>;\n /**\n * enumerable to determine if the input box has focus on render or not.\n * When undefined nothing has focus on render\n */\n autoFocus?: 'sendBoxTextField';\n /* @conditional-compile-remove(attachment-upload) */\n /**\n * Optional callback to render uploaded attachments in the SendBox. The sendBox will expand\n * vertically to accommodate the uploaded attachments. Attachment uploads will\n * be rendered below the text area in sendBox.\n * @beta\n */\n onRenderAttachmentUploads?: () => JSX.Element;\n /* @conditional-compile-remove(attachment-upload) */\n /**\n * Optional array of type {@link AttachmentMetadataWithProgress}\n * to render attachments being uploaded in the SendBox.\n * @beta\n */\n attachmentsWithProgress?: AttachmentMetadataWithProgress[];\n /* @conditional-compile-remove(attachment-upload) */\n /**\n * Optional callback to remove the attachment upload before sending by clicking on\n * cancel icon.\n * @beta\n */\n onCancelAttachmentUpload?: (attachmentId: string) => void;\n}\n\n/**\n * Component for typing and sending messages.\n *\n * Supports sending typing notification when user starts entering text.\n * Supports an optional message below the text input field.\n *\n * @public\n */\nexport const SendBox = (props: SendBoxProps): JSX.Element => {\n const {\n disabled,\n systemMessage,\n supportNewline,\n onSendMessage,\n onTyping,\n onRenderIcon,\n onRenderSystemMessage,\n styles,\n autoFocus,\n /* @conditional-compile-remove(mention) */\n mentionLookupOptions,\n /* @conditional-compile-remove(attachment-upload) */\n attachmentsWithProgress\n } = props;\n const theme = useTheme();\n const localeStrings = useLocale().strings.sendBox;\n const strings = { ...localeStrings, ...props.strings };\n const ids = useIdentifiers();\n\n const [textValue, setTextValue] = useState('');\n const [textValueOverflow, setTextValueOverflow] = useState(false);\n\n const sendTextFieldRef = React.useRef<ITextField>(null);\n\n /* @conditional-compile-remove(attachment-upload) */\n const [attachmentUploadsPendingError, setAttachmentUploadsPendingError] = useState<SendBoxErrorBarError | undefined>(\n undefined\n );\n\n const sendMessageOnClick = (): void => {\n // don't send a message when disabled\n if (disabled || textValueOverflow) {\n return;\n }\n\n // Don't send message until all attachments have been uploaded successfully\n /* @conditional-compile-remove(attachment-upload) */\n setAttachmentUploadsPendingError(undefined);\n\n /* @conditional-compile-remove(attachment-upload) */\n if (hasIncompleteAttachmentUploads(attachmentsWithProgress)) {\n setAttachmentUploadsPendingError({ message: strings.attachmentUploadsPendingError, timestamp: Date.now() });\n return;\n }\n\n const message = textValue;\n // we don't want to send empty messages including spaces, newlines, tabs\n // Message can be empty if there is a valid attachment upload\n if (\n sanitizeText(message).length > 0 ||\n /* @conditional-compile-remove(attachment-upload) */ hasCompletedAttachmentUploads(attachmentsWithProgress)\n ) {\n onSendMessage && onSendMessage(message);\n setTextValue('');\n }\n sendTextFieldRef.current?.focus();\n };\n\n const setText = (newValue?: string | undefined): void => {\n if (newValue === undefined) {\n return;\n }\n\n setTextValueOverflow(isMessageTooLong(newValue.length));\n setTextValue(newValue);\n };\n\n const textTooLongMessage = textValueOverflow ? strings.textTooLong : undefined;\n const errorMessage = systemMessage ?? textTooLongMessage;\n\n const mergedSendButtonStyle = useMemo(\n () => mergeStyles(sendButtonStyle, styles?.sendMessageIconContainer),\n [styles?.sendMessageIconContainer]\n );\n\n const mergedStyles = useMemo(() => concatStyleSets(styles), [styles]);\n\n const mergedSendIconStyle = useMemo(\n () =>\n sendIconStyle({\n theme,\n hasText: !!textValue,\n /* @conditional-compile-remove(attachment-upload) */ hasAttachment:\n hasCompletedAttachmentUploads(attachmentsWithProgress),\n hasErrorMessage: !!errorMessage,\n customSendIconStyle: styles?.sendMessageIcon\n }),\n [\n theme,\n textValue,\n /* @conditional-compile-remove(attachment-upload) */ attachmentsWithProgress,\n errorMessage,\n styles?.sendMessageIcon\n ]\n );\n\n const onRenderSendIcon = useCallback(\n (isHover: boolean) =>\n onRenderIcon ? (\n onRenderIcon(isHover)\n ) : (\n <Icon iconName={isHover && textValue ? 'SendBoxSendHovered' : 'SendBoxSend'} className={mergedSendIconStyle} />\n ),\n [mergedSendIconStyle, onRenderIcon, textValue]\n );\n\n // Ensure that errors are cleared when there are no attachments in sendBox\n /* @conditional-compile-remove(attachment-upload) */\n React.useEffect(() => {\n if (!attachmentsWithProgress?.filter((upload) => !upload.error).length) {\n setAttachmentUploadsPendingError(undefined);\n }\n }, [attachmentsWithProgress]);\n\n /* @conditional-compile-remove(attachment-upload) */\n const sendBoxErrorsProps = useMemo(() => {\n return {\n attachmentUploadsPendingError: attachmentUploadsPendingError,\n attachmentProgressError: attachmentsWithProgress?.filter((attachmentUpload) => attachmentUpload.error).pop()\n ?.error\n };\n }, [attachmentsWithProgress, attachmentUploadsPendingError]);\n\n /* @conditional-compile-remove(attachment-upload) */\n const onRenderAttachmentUploads = useCallback(() => {\n if (!attachmentsWithProgress?.filter((upload) => !upload.error).length) {\n return null;\n }\n return props.onRenderAttachmentUploads ? (\n props.onRenderAttachmentUploads()\n ) : (\n <Stack className={attachmentUploadCardsStyles}>\n <FluentV9ThemeProvider v8Theme={theme}>\n <_AttachmentUploadCards\n attachmentsWithProgress={attachmentsWithProgress}\n onCancelAttachmentUpload={props.onCancelAttachmentUpload}\n strings={{\n removeAttachment: props.strings?.removeAttachment ?? localeStrings.removeAttachment,\n uploading: props.strings?.uploading ?? localeStrings.uploading,\n uploadCompleted: props.strings?.uploadCompleted ?? localeStrings.uploadCompleted,\n attachmentMoreMenu: props.strings?.attachmentMoreMenu ?? localeStrings.attachmentMoreMenu\n }}\n />\n </FluentV9ThemeProvider>\n </Stack>\n );\n }, [\n attachmentsWithProgress,\n props,\n theme,\n localeStrings.removeAttachment,\n localeStrings.uploading,\n localeStrings.uploadCompleted,\n localeStrings.attachmentMoreMenu\n ]);\n\n return (\n <Stack\n className={mergeStyles(\n sendBoxWrapperStyles,\n { overflow: 'visible' } // This is needed for the mention popup to be visible\n )}\n >\n {\n /* @conditional-compile-remove(attachment-upload) */\n <SendBoxErrors\n attachmentProgressError={\n sendBoxErrorsProps.attachmentProgressError\n ? {\n message: sendBoxErrorsProps.attachmentProgressError.message,\n timestamp: Date.now()\n }\n : undefined\n }\n attachmentUploadsPendingError={sendBoxErrorsProps.attachmentUploadsPendingError}\n />\n }\n <Stack\n className={borderAndBoxShadowStyle({\n theme,\n hasErrorMessage: !!errorMessage,\n disabled: !!disabled\n })}\n >\n <InputBoxComponent\n autoFocus={autoFocus}\n data-ui-id={ids.sendboxTextField}\n disabled={disabled}\n errorMessage={onRenderSystemMessage ? onRenderSystemMessage(errorMessage) : errorMessage}\n textFieldRef={sendTextFieldRef}\n id=\"sendbox\"\n placeholderText={strings.placeholderText}\n textValue={textValue}\n onChange={(_, newValue) => setText(newValue)}\n onKeyDown={(ev) => {\n const keyWasSendingMessage = ev.key === 'Enter' && (ev.shiftKey === false || !supportNewline);\n if (!keyWasSendingMessage) {\n onTyping?.();\n }\n }}\n onEnterKeyDown={() => {\n sendMessageOnClick();\n }}\n styles={mergedStyles}\n supportNewline={supportNewline}\n maxLength={MAXIMUM_LENGTH_OF_MESSAGE}\n /* @conditional-compile-remove(mention) */\n mentionLookupOptions={mentionLookupOptions}\n >\n <InputBoxButton\n onRenderIcon={onRenderSendIcon}\n onClick={(e) => {\n if (!textValueOverflow) {\n sendMessageOnClick();\n }\n e.stopPropagation();\n }}\n id={'sendIconWrapper'}\n className={mergedSendButtonStyle}\n ariaLabel={localeStrings.sendButtonAriaLabel}\n tooltipContent={localeStrings.sendButtonAriaLabel}\n />\n </InputBoxComponent>\n {\n /* @conditional-compile-remove(attachment-upload) */\n onRenderAttachmentUploads()\n }\n </Stack>\n </Stack>\n );\n};\n"]}
|
1
|
+
{"version":3,"file":"SendBox.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/SendBox.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport React, { useState, useMemo, useCallback } from 'react';\nimport { IStyle, ITextField, mergeStyles, concatStyleSets, Icon, Stack } from '@fluentui/react';\nimport { sendButtonStyle, sendIconStyle, sendBoxWrapperStyles, borderAndBoxShadowStyle } from './styles/SendBox.styles';\nimport { BaseCustomStyles } from '../types';\nimport { useTheme } from '../theming';\nimport { useLocale } from '../localization';\nimport { useIdentifiers } from '../identifiers';\nimport { InputBoxComponent } from './InputBoxComponent';\nimport { InputBoxButton } from './InputBoxButton';\n/* @conditional-compile-remove(attachment-upload) */\nimport { SendBoxErrors } from './SendBoxErrors';\n/* @conditional-compile-remove(attachment-upload) */\nimport { _AttachmentUploadCards } from './AttachmentUploadCards';\n/* @conditional-compile-remove(attachment-upload) */\nimport { AttachmentMetadataWithProgress } from '../types/Attachment';\n/* @conditional-compile-remove(attachment-upload) */\nimport { attachmentUploadCardsStyles } from './styles/SendBox.styles';\n/* @conditional-compile-remove(attachment-upload) */\nimport { SendBoxErrorBarError } from './SendBoxErrorBar';\n/* @conditional-compile-remove(attachment-upload) */\nimport { hasCompletedAttachmentUploads, hasIncompleteAttachmentUploads } from './utils/SendBoxUtils';\nimport {\n MAXIMUM_LENGTH_OF_MESSAGE,\n isMessageTooLong,\n sanitizeText,\n isSendBoxButtonAriaDisabled\n} from './utils/SendBoxUtils';\n/* @conditional-compile-remove(mention) */\nimport { MentionLookupOptions } from './MentionPopover';\n/* @conditional-compile-remove(attachment-upload) */\nimport { FluentV9ThemeProvider } from '../theming/FluentV9ThemeProvider';\n\n/**\n * Fluent styles for {@link Sendbox}.\n *\n * @public\n */\nexport interface SendBoxStylesProps extends BaseCustomStyles {\n /** Styles for the text field. */\n textField?: IStyle;\n /** styles for the text field container */\n textFieldContainer?: IStyle;\n /** Styles for the container of the send message icon. */\n sendMessageIconContainer?: IStyle;\n /** Styles for the send message icon; These styles will be ignored when a custom send message icon is provided. */\n sendMessageIcon?: IStyle;\n /** Styles for the system message; These styles will be ignored when a custom system message component is provided. */\n systemMessage?: IStyle;\n}\n\n/**\n * Strings of {@link SendBox} that can be overridden.\n *\n * @public\n */\nexport interface SendBoxStrings {\n /**\n * Placeholder text in SendBox when there is no user input\n */\n placeholderText: string;\n /**\n * The warning message when send box text length is more than max limit\n */\n textTooLong: string;\n /**\n * Aria label for send message button\n */\n sendButtonAriaLabel: string;\n /* @conditional-compile-remove(attachment-upload) */\n /**\n * Error message indicating that all attachment uploads are not complete.\n */\n attachmentUploadsPendingError: string;\n /* @conditional-compile-remove(attachment-upload) */\n /**\n * Aria label to notify user when focus is on cancel attachment upload button.\n */\n removeAttachment: string;\n /* @conditional-compile-remove(attachment-upload) */\n /**\n * Aria label to notify user attachment uploading starts.\n */\n uploading: string;\n /* @conditional-compile-remove(attachment-upload) */\n /**\n * Aria label to notify user attachment is uploaded.\n */\n uploadCompleted: string;\n /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */\n /**\n * Aria label to notify user more attachment action menu.\n */\n attachmentMoreMenu: string;\n}\n\n/**\n * Props for {@link SendBox}.\n *\n * @public\n */\nexport interface SendBoxProps {\n /**\n * Optional boolean to disable text box\n * @defaultValue false\n */\n disabled?: boolean;\n /**\n * Optional text for system message below text box\n */\n systemMessage?: string;\n /**\n * Optional override behavior on send button click\n */\n onSendMessage?: (content: string) => Promise<void>;\n /* @conditional-compile-remove(mention) */\n /**\n * Optional props needed to lookup suggestions in the mention scenario.\n * @beta\n */\n mentionLookupOptions?: MentionLookupOptions;\n\n /**\n * Optional callback called when user is typing\n */\n onTyping?: () => Promise<void>;\n /**\n * Optional callback to render system message below the SendBox.\n * @defaultValue MessageBar\n */\n onRenderSystemMessage?: (systemMessage: string | undefined) => React.ReactElement;\n /**\n * Optional boolean to support new line in SendBox.\n * @defaultValue false\n */\n supportNewline?: boolean;\n /**\n * Optional callback to render send button icon to the right of the SendBox.\n * @defaultValue SendBoxSendHovered icon when mouse over icon and SendBoxSend icon otherwise\n */\n onRenderIcon?: (isHover: boolean) => JSX.Element;\n /**\n * Allows users to pass in an object contains custom CSS styles.\n * @Example\n * ```\n * <SendBox styles={{ root: { background: 'blue' } }} />\n * ```\n */\n styles?: SendBoxStylesProps;\n /**\n * Optional strings to override in component\n */\n strings?: Partial<SendBoxStrings>;\n /**\n * enumerable to determine if the input box has focus on render or not.\n * When undefined nothing has focus on render\n */\n autoFocus?: 'sendBoxTextField';\n /* @conditional-compile-remove(attachment-upload) */\n /**\n * Optional callback to render uploaded attachments in the SendBox. The sendBox will expand\n * vertically to accommodate the uploaded attachments. Attachment uploads will\n * be rendered below the text area in sendBox.\n * @beta\n */\n onRenderAttachmentUploads?: () => JSX.Element;\n /* @conditional-compile-remove(attachment-upload) */\n /**\n * Optional array of type {@link AttachmentMetadataWithProgress}\n * to render attachments being uploaded in the SendBox.\n * @beta\n */\n attachmentsWithProgress?: AttachmentMetadataWithProgress[];\n /* @conditional-compile-remove(attachment-upload) */\n /**\n * Optional callback to remove the attachment upload before sending by clicking on\n * cancel icon.\n * @beta\n */\n onCancelAttachmentUpload?: (attachmentId: string) => void;\n}\n\n/**\n * Component for typing and sending messages.\n *\n * Supports sending typing notification when user starts entering text.\n * Supports an optional message below the text input field.\n *\n * @public\n */\nexport const SendBox = (props: SendBoxProps): JSX.Element => {\n const {\n disabled,\n systemMessage,\n supportNewline,\n onSendMessage,\n onTyping,\n onRenderIcon,\n onRenderSystemMessage,\n styles,\n autoFocus,\n /* @conditional-compile-remove(mention) */\n mentionLookupOptions,\n /* @conditional-compile-remove(attachment-upload) */\n attachmentsWithProgress\n } = props;\n const theme = useTheme();\n const localeStrings = useLocale().strings.sendBox;\n const strings = { ...localeStrings, ...props.strings };\n const ids = useIdentifiers();\n\n const [textValue, setTextValue] = useState('');\n const [textValueOverflow, setTextValueOverflow] = useState(false);\n\n const sendTextFieldRef = React.useRef<ITextField>(null);\n\n /* @conditional-compile-remove(attachment-upload) */\n const [attachmentUploadsPendingError, setAttachmentUploadsPendingError] = useState<SendBoxErrorBarError | undefined>(\n undefined\n );\n\n const sendMessageOnClick = (): void => {\n // don't send a message when disabled\n if (disabled || textValueOverflow) {\n return;\n }\n\n // Don't send message until all attachments have been uploaded successfully\n /* @conditional-compile-remove(attachment-upload) */\n setAttachmentUploadsPendingError(undefined);\n\n /* @conditional-compile-remove(attachment-upload) */\n if (hasIncompleteAttachmentUploads(attachmentsWithProgress)) {\n setAttachmentUploadsPendingError({ message: strings.attachmentUploadsPendingError, timestamp: Date.now() });\n return;\n }\n\n const message = textValue;\n // we don't want to send empty messages including spaces, newlines, tabs\n // Message can be empty if there is a valid attachment upload\n if (\n sanitizeText(message).length > 0 ||\n /* @conditional-compile-remove(attachment-upload) */ hasCompletedAttachmentUploads(attachmentsWithProgress)\n ) {\n onSendMessage && onSendMessage(message);\n setTextValue('');\n sendTextFieldRef.current?.focus();\n }\n };\n\n const setText = (newValue?: string | undefined): void => {\n if (newValue === undefined) {\n return;\n }\n\n setTextValueOverflow(isMessageTooLong(newValue.length));\n setTextValue(newValue);\n };\n\n const textTooLongMessage = textValueOverflow ? strings.textTooLong : undefined;\n const errorMessage = systemMessage ?? textTooLongMessage;\n\n const mergedSendButtonStyle = useMemo(\n () => mergeStyles(sendButtonStyle, styles?.sendMessageIconContainer),\n [styles?.sendMessageIconContainer]\n );\n\n const mergedStyles = useMemo(() => concatStyleSets(styles), [styles]);\n\n const mergedSendIconStyle = useMemo(\n () =>\n sendIconStyle({\n theme,\n hasText: sanitizeText(textValue).length > 0,\n /* @conditional-compile-remove(attachment-upload) */ hasAttachment:\n hasCompletedAttachmentUploads(attachmentsWithProgress),\n hasErrorMessage: !!errorMessage,\n customSendIconStyle: styles?.sendMessageIcon,\n disabled: !!disabled\n }),\n [\n theme,\n textValue,\n /* @conditional-compile-remove(attachment-upload) */ attachmentsWithProgress,\n errorMessage,\n styles?.sendMessageIcon,\n disabled\n ]\n );\n\n const isSendBoxButtonAriaDisabledValue = useMemo(() => {\n return isSendBoxButtonAriaDisabled({\n hasContent: sanitizeText(textValue).length > 0,\n /* @conditional-compile-remove(attachment-upload) */ hasCompletedAttachmentUploads:\n hasCompletedAttachmentUploads(attachmentsWithProgress),\n hasError: !!errorMessage,\n disabled: !!disabled\n });\n }, [/* @conditional-compile-remove(attachment-upload) */ attachmentsWithProgress, disabled, errorMessage, textValue]);\n\n const onRenderSendIcon = useCallback(\n (isHover: boolean) =>\n onRenderIcon ? (\n onRenderIcon(isHover)\n ) : (\n <Icon iconName={isHover && textValue ? 'SendBoxSendHovered' : 'SendBoxSend'} className={mergedSendIconStyle} />\n ),\n [mergedSendIconStyle, onRenderIcon, textValue]\n );\n\n // Ensure that errors are cleared when there are no attachments in sendBox\n /* @conditional-compile-remove(attachment-upload) */\n React.useEffect(() => {\n if (!attachmentsWithProgress?.filter((upload) => !upload.error).length) {\n setAttachmentUploadsPendingError(undefined);\n }\n }, [attachmentsWithProgress]);\n\n /* @conditional-compile-remove(attachment-upload) */\n const sendBoxErrorsProps = useMemo(() => {\n return {\n attachmentUploadsPendingError: attachmentUploadsPendingError,\n attachmentProgressError: attachmentsWithProgress?.filter((attachmentUpload) => attachmentUpload.error).pop()\n ?.error\n };\n }, [attachmentsWithProgress, attachmentUploadsPendingError]);\n\n /* @conditional-compile-remove(attachment-upload) */\n const onRenderAttachmentUploads = useCallback(() => {\n if (!attachmentsWithProgress?.filter((upload) => !upload.error).length) {\n return null;\n }\n return props.onRenderAttachmentUploads ? (\n props.onRenderAttachmentUploads()\n ) : (\n <Stack className={attachmentUploadCardsStyles}>\n <FluentV9ThemeProvider v8Theme={theme}>\n <_AttachmentUploadCards\n attachmentsWithProgress={attachmentsWithProgress}\n onCancelAttachmentUpload={props.onCancelAttachmentUpload}\n strings={{\n removeAttachment: props.strings?.removeAttachment ?? localeStrings.removeAttachment,\n uploading: props.strings?.uploading ?? localeStrings.uploading,\n uploadCompleted: props.strings?.uploadCompleted ?? localeStrings.uploadCompleted,\n attachmentMoreMenu: props.strings?.attachmentMoreMenu ?? localeStrings.attachmentMoreMenu\n }}\n />\n </FluentV9ThemeProvider>\n </Stack>\n );\n }, [\n attachmentsWithProgress,\n props,\n theme,\n localeStrings.removeAttachment,\n localeStrings.uploading,\n localeStrings.uploadCompleted,\n localeStrings.attachmentMoreMenu\n ]);\n\n return (\n <Stack\n className={mergeStyles(\n sendBoxWrapperStyles,\n { overflow: 'visible' } // This is needed for the mention popup to be visible\n )}\n >\n {\n /* @conditional-compile-remove(attachment-upload) */\n <SendBoxErrors\n attachmentProgressError={\n sendBoxErrorsProps.attachmentProgressError\n ? {\n message: sendBoxErrorsProps.attachmentProgressError.message,\n timestamp: Date.now()\n }\n : undefined\n }\n attachmentUploadsPendingError={sendBoxErrorsProps.attachmentUploadsPendingError}\n />\n }\n <Stack\n className={borderAndBoxShadowStyle({\n theme,\n hasErrorMessage: !!errorMessage,\n disabled: !!disabled\n })}\n >\n <InputBoxComponent\n autoFocus={autoFocus}\n data-ui-id={ids.sendboxTextField}\n disabled={disabled}\n errorMessage={onRenderSystemMessage ? onRenderSystemMessage(errorMessage) : errorMessage}\n textFieldRef={sendTextFieldRef}\n id=\"sendbox\"\n placeholderText={strings.placeholderText}\n textValue={textValue}\n onChange={(_, newValue) => setText(newValue)}\n onKeyDown={(ev) => {\n const keyWasSendingMessage = ev.key === 'Enter' && (ev.shiftKey === false || !supportNewline);\n if (!keyWasSendingMessage) {\n onTyping?.();\n }\n }}\n onEnterKeyDown={() => {\n sendMessageOnClick();\n }}\n styles={mergedStyles}\n supportNewline={supportNewline}\n maxLength={MAXIMUM_LENGTH_OF_MESSAGE}\n /* @conditional-compile-remove(mention) */\n mentionLookupOptions={mentionLookupOptions}\n >\n <InputBoxButton\n onRenderIcon={onRenderSendIcon}\n onClick={(e) => {\n if (!textValueOverflow) {\n sendMessageOnClick();\n }\n e.stopPropagation();\n }}\n id={'sendIconWrapper'}\n className={mergedSendButtonStyle}\n ariaLabel={localeStrings.sendButtonAriaLabel}\n tooltipContent={localeStrings.sendButtonAriaLabel}\n ariaDisabled={isSendBoxButtonAriaDisabledValue}\n />\n </InputBoxComponent>\n {\n /* @conditional-compile-remove(attachment-upload) */\n onRenderAttachmentUploads()\n }\n </Stack>\n </Stack>\n );\n};\n"]}
|
@@ -19,4 +19,19 @@ export declare const isMessageTooLong: (valueLength: number) => boolean;
|
|
19
19
|
* @private
|
20
20
|
*/
|
21
21
|
export declare const sanitizeText: (message: string) => string;
|
22
|
+
/**
|
23
|
+
* Determines whether the send box should be disabled for ARIA accessibility.
|
24
|
+
*
|
25
|
+
* @param hasContent - Indicates whether the send box has content.
|
26
|
+
* @param hasCompletedAttachmentUploads - Indicates whether attachment uploads have completed.
|
27
|
+
* @param hasError - Indicates whether there is an error.
|
28
|
+
* @param disabled - Indicates whether the send box is disabled.
|
29
|
+
* @returns A boolean value indicating whether the send box should be disabled for ARIA accessibility.
|
30
|
+
*/
|
31
|
+
export declare const isSendBoxButtonAriaDisabled: ({ hasContent, hasCompletedAttachmentUploads, hasError, disabled }: {
|
32
|
+
hasContent: boolean;
|
33
|
+
hasCompletedAttachmentUploads: boolean;
|
34
|
+
hasError: boolean;
|
35
|
+
disabled: boolean;
|
36
|
+
}) => boolean;
|
22
37
|
//# sourceMappingURL=SendBoxUtils.d.ts.map
|
@@ -39,4 +39,23 @@ export const sanitizeText = (message) => {
|
|
39
39
|
return message;
|
40
40
|
}
|
41
41
|
};
|
42
|
+
/**
|
43
|
+
* Determines whether the send box should be disabled for ARIA accessibility.
|
44
|
+
*
|
45
|
+
* @param hasContent - Indicates whether the send box has content.
|
46
|
+
* @param hasCompletedAttachmentUploads - Indicates whether attachment uploads have completed.
|
47
|
+
* @param hasError - Indicates whether there is an error.
|
48
|
+
* @param disabled - Indicates whether the send box is disabled.
|
49
|
+
* @returns A boolean value indicating whether the send box should be disabled for ARIA accessibility.
|
50
|
+
*/
|
51
|
+
export const isSendBoxButtonAriaDisabled = ({ hasContent,
|
52
|
+
/* @conditional-compile-remove(attachment-upload) */
|
53
|
+
hasCompletedAttachmentUploads, hasError, disabled }) => {
|
54
|
+
return (
|
55
|
+
// no content
|
56
|
+
!(hasContent || /* @conditional-compile-remove(attachment-upload) */ hasCompletedAttachmentUploads) ||
|
57
|
+
//error message exists
|
58
|
+
hasError ||
|
59
|
+
disabled);
|
60
|
+
};
|
42
61
|
//# sourceMappingURL=SendBoxUtils.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"SendBoxUtils.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/utils/SendBoxUtils.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAKlC;;GAEG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,IAAI,CAAC;AAC9C,MAAM,mBAAmB,GAAG,OAAO,CAAC;AAEpC,oDAAoD;AACpD;;GAEG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAC5C,uBAAqE,EAC5D,EAAE;IACX,OAAO,CAAC,CAAC,CACP,CAAA,uBAAuB,aAAvB,uBAAuB,uBAAvB,uBAAuB,CAAE,MAAM;QAC/B,CAAC,uBAAuB;aACrB,MAAM,CAAC,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC;aACrD,KAAK,CAAC,CAAC,gBAAgB,EAAE,EAAE,CAAC,gBAAgB,CAAC,QAAQ,KAAK,CAAC,IAAI,gBAAgB,CAAC,QAAQ,KAAK,SAAS,CAAC,CAC3G,CAAC;AACJ,CAAC,CAAC;AAEF,oDAAoD;AACpD;;GAEG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAC3C,uBAAqE,EAC5D,EAAE;IACX,OAAO,CAAC,CAAC,CAAA,uBAAuB,aAAvB,uBAAuB,uBAAvB,uBAAuB,CAAE,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA,CAAC;AAC5E,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,WAAmB,EAAW,EAAE;IAC/D,OAAO,WAAW,GAAG,yBAAyB,CAAC;AACjD,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,OAAe,EAAU,EAAE;IACtD,IAAI,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACtC,OAAO,EAAE,CAAC;IACZ,CAAC;SAAM,CAAC;QACN,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/* @conditional-compile-remove(attachment-upload) */\nimport { AttachmentMetadataWithProgress } from '../../types/Attachment';\n\n/**\n * @private\n */\nexport const MAXIMUM_LENGTH_OF_MESSAGE = 8000;\nconst EMPTY_MESSAGE_REGEX = /^\\s*$/;\n\n/* @conditional-compile-remove(attachment-upload) */\n/**\n * @private\n */\nexport const hasIncompleteAttachmentUploads = (\n attachmentsWithProgress: AttachmentMetadataWithProgress[] | undefined\n): boolean => {\n return !!(\n attachmentsWithProgress?.length &&\n !attachmentsWithProgress\n .filter((attachmentUpload) => !attachmentUpload.error)\n .every((attachmentUpload) => attachmentUpload.progress === 1 && attachmentUpload.progress !== undefined)\n );\n};\n\n/* @conditional-compile-remove(attachment-upload) */\n/**\n * @private\n */\nexport const hasCompletedAttachmentUploads = (\n attachmentsWithProgress: AttachmentMetadataWithProgress[] | undefined\n): boolean => {\n return !!attachmentsWithProgress?.find((attachment) => !attachment.error);\n};\n\n/**\n * @private\n */\nexport const isMessageTooLong = (valueLength: number): boolean => {\n return valueLength > MAXIMUM_LENGTH_OF_MESSAGE;\n};\n\n/**\n * @private\n */\nexport const sanitizeText = (message: string): string => {\n if (EMPTY_MESSAGE_REGEX.test(message)) {\n return '';\n } else {\n return message;\n }\n};\n"]}
|
1
|
+
{"version":3,"file":"SendBoxUtils.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/utils/SendBoxUtils.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAKlC;;GAEG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,IAAI,CAAC;AAC9C,MAAM,mBAAmB,GAAG,OAAO,CAAC;AAEpC,oDAAoD;AACpD;;GAEG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAC5C,uBAAqE,EAC5D,EAAE;IACX,OAAO,CAAC,CAAC,CACP,CAAA,uBAAuB,aAAvB,uBAAuB,uBAAvB,uBAAuB,CAAE,MAAM;QAC/B,CAAC,uBAAuB;aACrB,MAAM,CAAC,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC;aACrD,KAAK,CAAC,CAAC,gBAAgB,EAAE,EAAE,CAAC,gBAAgB,CAAC,QAAQ,KAAK,CAAC,IAAI,gBAAgB,CAAC,QAAQ,KAAK,SAAS,CAAC,CAC3G,CAAC;AACJ,CAAC,CAAC;AAEF,oDAAoD;AACpD;;GAEG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAC3C,uBAAqE,EAC5D,EAAE;IACX,OAAO,CAAC,CAAC,CAAA,uBAAuB,aAAvB,uBAAuB,uBAAvB,uBAAuB,CAAE,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA,CAAC;AAC5E,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,WAAmB,EAAW,EAAE;IAC/D,OAAO,WAAW,GAAG,yBAAyB,CAAC;AACjD,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,OAAe,EAAU,EAAE;IACtD,IAAI,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACtC,OAAO,EAAE,CAAC;IACZ,CAAC;SAAM,CAAC;QACN,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,EAC1C,UAAU;AACV,oDAAoD;AACpD,6BAA6B,EAC7B,QAAQ,EACR,QAAQ,EAOT,EAAW,EAAE;IACZ,OAAO;IACL,aAAa;IACb,CAAC,CAAC,UAAU,IAAI,oDAAoD,CAAC,6BAA6B,CAAC;QACnG,sBAAsB;QACtB,QAAQ;QACR,QAAQ,CACT,CAAC;AACJ,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/* @conditional-compile-remove(attachment-upload) */\nimport { AttachmentMetadataWithProgress } from '../../types/Attachment';\n\n/**\n * @private\n */\nexport const MAXIMUM_LENGTH_OF_MESSAGE = 8000;\nconst EMPTY_MESSAGE_REGEX = /^\\s*$/;\n\n/* @conditional-compile-remove(attachment-upload) */\n/**\n * @private\n */\nexport const hasIncompleteAttachmentUploads = (\n attachmentsWithProgress: AttachmentMetadataWithProgress[] | undefined\n): boolean => {\n return !!(\n attachmentsWithProgress?.length &&\n !attachmentsWithProgress\n .filter((attachmentUpload) => !attachmentUpload.error)\n .every((attachmentUpload) => attachmentUpload.progress === 1 && attachmentUpload.progress !== undefined)\n );\n};\n\n/* @conditional-compile-remove(attachment-upload) */\n/**\n * @private\n */\nexport const hasCompletedAttachmentUploads = (\n attachmentsWithProgress: AttachmentMetadataWithProgress[] | undefined\n): boolean => {\n return !!attachmentsWithProgress?.find((attachment) => !attachment.error);\n};\n\n/**\n * @private\n */\nexport const isMessageTooLong = (valueLength: number): boolean => {\n return valueLength > MAXIMUM_LENGTH_OF_MESSAGE;\n};\n\n/**\n * @private\n */\nexport const sanitizeText = (message: string): string => {\n if (EMPTY_MESSAGE_REGEX.test(message)) {\n return '';\n } else {\n return message;\n }\n};\n\n/**\n * Determines whether the send box should be disabled for ARIA accessibility.\n *\n * @param hasContent - Indicates whether the send box has content.\n * @param hasCompletedAttachmentUploads - Indicates whether attachment uploads have completed.\n * @param hasError - Indicates whether there is an error.\n * @param disabled - Indicates whether the send box is disabled.\n * @returns A boolean value indicating whether the send box should be disabled for ARIA accessibility.\n */\nexport const isSendBoxButtonAriaDisabled = ({\n hasContent,\n /* @conditional-compile-remove(attachment-upload) */\n hasCompletedAttachmentUploads,\n hasError,\n disabled\n}: {\n hasContent: boolean;\n /* @conditional-compile-remove(attachment-upload) */\n hasCompletedAttachmentUploads: boolean;\n hasError: boolean;\n disabled: boolean;\n}): boolean => {\n return (\n // no content\n !(hasContent || /* @conditional-compile-remove(attachment-upload) */ hasCompletedAttachmentUploads) ||\n //error message exists\n hasError ||\n disabled\n );\n};\n"]}
|
@@ -38,6 +38,7 @@ import { useTrackedCapabilityChangedNotifications } from './utils/TrackCapabilit
|
|
38
38
|
import { useEndedCallConsoleErrors } from './utils/useConsoleErrors';
|
39
39
|
/* @conditional-compile-remove(end-of-call-survey) */
|
40
40
|
import { SurveyPage } from './pages/SurveyPage';
|
41
|
+
import { useAudio } from '../common/AudioProvider';
|
41
42
|
const isShowing = (overrideSidePane) => {
|
42
43
|
return !!(overrideSidePane === null || overrideSidePane === void 0 ? void 0 : overrideSidePane.isActive);
|
43
44
|
};
|
@@ -96,7 +97,7 @@ const MainScreen = (props) => {
|
|
96
97
|
adapter.off('callEnded', closeSidePane);
|
97
98
|
};
|
98
99
|
}, [adapter]);
|
99
|
-
const compositeAudioContext =
|
100
|
+
const compositeAudioContext = useAudio();
|
100
101
|
const capabilitiesChangedInfoAndRole = useSelector(capabilitiesChangedInfoAndRoleSelector);
|
101
102
|
const capabilitiesChangedNotificationBarProps = useTrackedCapabilityChangedNotifications(capabilitiesChangedInfoAndRole);
|
102
103
|
// Track the last dismissed errors of any error kind to prevent errors from re-appearing on subsequent page navigation
|
@@ -171,7 +172,7 @@ const MainScreen = (props) => {
|
|
171
172
|
pageElement = (React.createElement(TransferPage, { mobileView: props.mobileView, modalLayerHostId: props.modalLayerHostId, options: props.options, updateSidePaneRenderer: setSidePaneRenderer, mobileChatTabHeader: props.mobileChatTabHeader, onFetchAvatarPersonaData: onFetchAvatarPersonaData, latestErrors: latestErrors, onDismissError: onDismissError, capabilitiesChangedNotificationBarProps: capabilitiesChangedNotificationBarProps }));
|
172
173
|
break;
|
173
174
|
case 'call':
|
174
|
-
pageElement = (React.createElement(CallPage, { callInvitationURL: callInvitationUrl, onFetchAvatarPersonaData: onFetchAvatarPersonaData, onFetchParticipantMenuItems: onFetchParticipantMenuItems, mobileView: props.mobileView, modalLayerHostId: props.modalLayerHostId, options: props.options, updateSidePaneRenderer: setSidePaneRenderer, mobileChatTabHeader: props.mobileChatTabHeader, onCloseChatPane: props.onCloseChatPane, latestErrors: latestErrors, onDismissError: onDismissError, galleryLayout: userSetGalleryLayout, onUserSetGalleryLayoutChange: setUserSetGalleryLayout, onSetUserSetOverflowGalleryPosition: setUserSetOverflowGalleryPosition, userSetOverflowGalleryPosition: userSetOverflowGalleryPosition, capabilitiesChangedNotificationBarProps: capabilitiesChangedNotificationBarProps, pinnedParticipants: pinnedParticipants, setPinnedParticipants: setPinnedParticipants, compositeAudioContext: compositeAudioContext
|
175
|
+
pageElement = (React.createElement(CallPage, { callInvitationURL: callInvitationUrl, onFetchAvatarPersonaData: onFetchAvatarPersonaData, onFetchParticipantMenuItems: onFetchParticipantMenuItems, mobileView: props.mobileView, modalLayerHostId: props.modalLayerHostId, options: props.options, updateSidePaneRenderer: setSidePaneRenderer, mobileChatTabHeader: props.mobileChatTabHeader, onCloseChatPane: props.onCloseChatPane, latestErrors: latestErrors, onDismissError: onDismissError, galleryLayout: userSetGalleryLayout, onUserSetGalleryLayoutChange: setUserSetGalleryLayout, onSetUserSetOverflowGalleryPosition: setUserSetOverflowGalleryPosition, userSetOverflowGalleryPosition: userSetOverflowGalleryPosition, capabilitiesChangedNotificationBarProps: capabilitiesChangedNotificationBarProps, pinnedParticipants: pinnedParticipants, setPinnedParticipants: setPinnedParticipants, compositeAudioContext: compositeAudioContext }));
|
175
176
|
break;
|
176
177
|
/* @conditional-compile-remove(PSTN-calls) */ /* @conditional-compile-remove(one-to-n-calling) */
|
177
178
|
case 'hold':
|