@azure/communication-react 1.18.0-alpha-202407040014 → 1.18.0-alpha-202407060013
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 +117 -27
- package/dist/dist-cjs/communication-react/{ChatMessageComponentAsRichTextEditBox-DI2PbeU3.js → ChatMessageComponentAsRichTextEditBox-DMEk2o-G.js} +2 -2
- package/dist/dist-cjs/communication-react/{ChatMessageComponentAsRichTextEditBox-DI2PbeU3.js.map → ChatMessageComponentAsRichTextEditBox-DMEk2o-G.js.map} +1 -1
- package/dist/dist-cjs/communication-react/{RichTextSendBoxWrapper-ByURv_W1.js → RichTextSendBoxWrapper-ByJFtf0Z.js} +2 -2
- package/dist/dist-cjs/communication-react/{RichTextSendBoxWrapper-ByURv_W1.js.map → RichTextSendBoxWrapper-ByJFtf0Z.js.map} +1 -1
- package/dist/dist-cjs/communication-react/{index-BCxHilMO.js → index-BPO9X27C.js} +860 -519
- package/dist/dist-cjs/communication-react/index-BPO9X27C.js.map +1 -0
- package/dist/dist-cjs/communication-react/index.js +1 -1
- package/dist/dist-esm/acs-ui-common/src/common.d.ts +13 -0
- package/dist/dist-esm/acs-ui-common/src/common.js.map +1 -1
- package/dist/dist-esm/acs-ui-common/src/dataConversion.d.ts +6 -0
- package/dist/dist-esm/acs-ui-common/src/dataConversion.js +17 -0
- package/dist/dist-esm/acs-ui-common/src/dataConversion.js.map +1 -0
- package/dist/dist-esm/acs-ui-common/src/index.d.ts +2 -0
- package/dist/dist-esm/acs-ui-common/src/index.js +2 -0
- package/dist/dist-esm/acs-ui-common/src/index.js.map +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-stateful-client/src/CallClientState.d.ts +1 -1
- package/dist/dist-esm/calling-stateful-client/src/CallClientState.js.map +1 -1
- package/dist/dist-esm/chat-component-bindings/src/handlers/createHandlers.d.ts +3 -0
- package/dist/dist-esm/chat-component-bindings/src/handlers/createHandlers.js +15 -0
- package/dist/dist-esm/chat-component-bindings/src/handlers/createHandlers.js.map +1 -1
- package/dist/dist-esm/communication-react/src/index.d.ts +1 -0
- package/dist/dist-esm/communication-react/src/index.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/MessageStatusIndicatorInternal.js +1 -1
- package/dist/dist-esm/react-components/src/components/MessageStatusIndicatorInternal.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/NotificationStack.d.ts +58 -26
- package/dist/dist-esm/react-components/src/components/NotificationStack.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/CopyPastePlugin.d.ts +6 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/CopyPastePlugin.js +27 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/CopyPastePlugin.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/UpdateContentPlugin.d.ts +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/UpdateContentPlugin.js +27 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/UpdateContentPlugin.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextEditor.d.ts +2 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextEditor.js +31 -14
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextEditor.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextInputBoxComponent.d.ts +2 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextInputBoxComponent.js +6 -2
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextInputBoxComponent.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextSendBox.d.ts +16 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextSendBox.js +73 -15
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextSendBox.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/styles/RichTextEditor.styles.js +7 -3
- package/dist/dist-esm/react-components/src/components/styles/RichTextEditor.styles.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/utils/RichTextEditorUtils.d.ts +5 -1
- package/dist/dist-esm/react-components/src/components/utils/RichTextEditorUtils.js +21 -0
- package/dist/dist-esm/react-components/src/components/utils/RichTextEditorUtils.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/utils/SendBoxUtils.d.ts +4 -0
- package/dist/dist-esm/react-components/src/components/utils/SendBoxUtils.js +15 -0
- package/dist/dist-esm/react-components/src/components/utils/SendBoxUtils.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/utils.js +16 -1
- package/dist/dist-esm/react-components/src/components/utils.js.map +1 -1
- package/dist/dist-esm/react-components/src/localization/locales/en-US/strings.json +40 -0
- package/dist/dist-esm/react-components/src/theming/icons.d.ts +1 -0
- package/dist/dist-esm/react-components/src/theming/icons.js +4 -0
- package/dist/dist-esm/react-components/src/theming/icons.js.map +1 -1
- package/dist/dist-esm/react-components/src/types/Attachment.d.ts +4 -0
- package/dist/dist-esm/react-components/src/types/Attachment.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/CallComposite.js +65 -13
- package/dist/dist-esm/react-composites/src/composites/CallComposite/CallComposite.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/CallArrangement.d.ts +1 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/CallArrangement.js +8 -3
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/CallArrangement.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/CallPage.d.ts +1 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/CallPage.js +6 -2
- package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/CallPage.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/HoldPage.d.ts +1 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/HoldPage.js +3 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/HoldPage.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/LobbyPage.d.ts +1 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/LobbyPage.js +3 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/LobbyPage.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/TransferPage.js +5 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/TransferPage.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/TrackErrors.d.ts +6 -6
- package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/TrackErrors.js +22 -20
- package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/TrackErrors.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/Utils.d.ts +47 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/Utils.js +104 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/Utils.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/AzureCommunicationCallWithChatAdapter.d.ts +5 -0
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/AzureCommunicationCallWithChatAdapter.js +22 -0
- 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 +13 -0
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/CallWithChatAdapter.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/CallWithChatBackedChatAdapter.d.ts +5 -0
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/CallWithChatBackedChatAdapter.js +16 -0
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/CallWithChatBackedChatAdapter.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/ChatScreen.js +19 -2
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/ChatScreen.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/adapter/AzureCommunicationChatAdapter.d.ts +3 -0
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/adapter/AzureCommunicationChatAdapter.js +20 -0
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/adapter/AzureCommunicationChatAdapter.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/adapter/ChatAdapter.d.ts +9 -0
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/adapter/ChatAdapter.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/file-sharing/AttachmentUpload.d.ts +1 -1
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/file-sharing/AttachmentUpload.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/hooks/useHandlers.js +4 -0
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/hooks/useHandlers.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/image-upload/useImageUpload.d.ts +12 -0
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/image-upload/useImageUpload.js +129 -0
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/image-upload/useImageUpload.js.map +1 -0
- package/dist/dist-esm/react-composites/src/composites/common/SendBoxPicker.d.ts +3 -0
- package/dist/dist-esm/react-composites/src/composites/common/SendBoxPicker.js +1 -2
- package/dist/dist-esm/react-composites/src/composites/common/SendBoxPicker.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/icons.d.ts +1 -0
- package/package.json +2 -2
- package/dist/dist-cjs/communication-react/index-BCxHilMO.js.map +0 -1
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"MessageStatusIndicatorInternal.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/MessageStatusIndicatorInternal.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { ICalloutContentStyles, ITooltipHostStyles, mergeStyles, TooltipHost } from '@fluentui/react';\nimport { MessageStatus, _formatString } from '@internal/acs-ui-common';\nimport React, { useState } from 'react';\nimport { useLocale } from '../localization';\nimport { useTheme } from '../theming';\nimport { isDarkThemed } from '../theming/themeUtils';\nimport { BaseCustomStyles } from '../types';\nimport {\n MessageStatusIndicatorErrorIconStyle,\n MessageStatusIndicatorIconStyle\n} from './styles/MessageStatusIndicator.styles';\nimport { MessageStatusIndicatorStrings } from './MessageStatusIndicator';\nimport { MessageStatusIcon, MessageStatusIconProps } from './MessageStatusIcon';\n\n/**\n * Props for {@link MessageStatusIndicatorInternal}.\n *\n * @internal\n */\nexport interface MessageStatusIndicatorInternalProps {\n /** Message status that determines the icon to display. */\n status?: MessageStatus;\n readCount?: number;\n onToggleToolTip?: (isToggled: boolean) => void;\n /** number of participants not including myself */\n remoteParticipantsCount?: number;\n /**\n * Allows users to pass an object containing custom CSS styles.\n * @Example\n * ```\n * <MessageStatus styles={{ root: { background: 'blue' } }} />\n * ```\n */\n styles?: BaseCustomStyles;\n /**\n * Optional strings to override in component\n */\n strings?: MessageStatusIndicatorStrings;\n /**\n * Optional call back to provide LiveMessage component for accessibility\n */\n shouldAnnounce: boolean;\n}\n\n/**\n * Component to display the status of a sent message.\n *\n * Adds an icon and tooltip corresponding to the message status.\n *\n * @internal\n */\nexport const MessageStatusIndicatorInternal = (props: MessageStatusIndicatorInternalProps): JSX.Element => {\n const { status, styles, remoteParticipantsCount, onToggleToolTip, readCount, shouldAnnounce } = props;\n const localeStrings = useLocale().strings.messageStatusIndicator;\n const [isTooltipToggled, setIsTooltipToggled] = useState<boolean>(false);\n const strings = { ...localeStrings, ...props.strings };\n const theme = useTheme();\n\n const calloutStyle: Partial<ICalloutContentStyles> = { root: { padding: 0 }, calloutMain: { padding: '0.5rem' } };\n\n // Place callout with no gap between it and the button.\n const calloutProps = {\n gapSpace: 0,\n styles: calloutStyle,\n backgroundColor: isDarkThemed(theme) ? theme.palette.neutralLighter : ''\n };\n\n switch (status) {\n case 'failed':\n return (\n <TooltipHost\n content={strings.failedToSendTooltipText}\n data-ui-id=\"chat-composite-message-tooltip\"\n calloutProps={{ ...calloutProps }}\n styles={hostStyles}\n >\n <MemoMessageStatusIcon\n shouldAnnounce={shouldAnnounce}\n iconName=\"MessageFailed\"\n iconClassName={mergeStyles(\n MessageStatusIndicatorErrorIconStyle,\n { color: theme.palette.redDark },\n styles?.root\n )}\n ariaLabel={strings.failedToSendAriaLabel}\n />\n </TooltipHost>\n );\n case 'sending':\n return (\n <TooltipHost\n content={strings.sendingTooltipText}\n data-ui-id=\"chat-composite-message-tooltip\"\n calloutProps={{ ...calloutProps }}\n styles={hostStyles}\n >\n <MemoMessageStatusIcon\n shouldAnnounce={shouldAnnounce}\n iconName=\"MessageSending\"\n iconClassName={mergeStyles(\n MessageStatusIndicatorIconStyle,\n { color: theme.palette.themePrimary },\n styles?.root\n )}\n ariaLabel={strings.sendingAriaLabel}\n />\n </TooltipHost>\n );\n case 'seen':\n return (\n <TooltipHost\n calloutProps={{ ...calloutProps }}\n data-ui-id=\"chat-composite-message-tooltip\"\n styles={hostStyles}\n content={\n // when it's just 1 to 1 texting, we don't need to know who has read the message, just show message as 'seen'\n // when readCount is 0, we have a bug, show 'seen' to cover up as a fall back\n // when participant count is 0, we have a bug, show 'seen' to cover up as a fall back\n readCount === 0 ||\n (remoteParticipantsCount && remoteParticipantsCount <= 1) ||\n !readCount ||\n !remoteParticipantsCount ||\n strings.readByTooltipText === undefined\n ? strings.seenTooltipText\n : _formatString(strings.readByTooltipText, {\n messageThreadReadCount: `${readCount}`,\n remoteParticipantsCount: `${remoteParticipantsCount}`\n })\n }\n onTooltipToggle={() => {\n if (onToggleToolTip) {\n onToggleToolTip(!isTooltipToggled);\n setIsTooltipToggled(!isTooltipToggled);\n }\n }}\n >\n <MemoMessageStatusIcon\n shouldAnnounce={shouldAnnounce}\n iconName=\"MessageSeen\"\n iconClassName={mergeStyles({ color: theme.palette.themePrimary }, styles?.root)}\n ariaLabel={strings.seenAriaLabel}\n />\n </TooltipHost>\n );\n case 'delivered':\n return (\n <TooltipHost\n calloutProps={{ ...calloutProps }}\n content={strings.deliveredTooltipText}\n data-ui-id=\"chat-composite-message-tooltip\"\n styles={hostStyles}\n >\n <MemoMessageStatusIcon\n shouldAnnounce={shouldAnnounce}\n iconName=\"MessageDelivered\"\n iconClassName={mergeStyles(\n MessageStatusIndicatorIconStyle,\n { color: theme.palette.themePrimary },\n styles?.root\n )}\n ariaLabel={strings.deliveredAriaLabel}\n />\n </TooltipHost>\n );\n default:\n return <></>;\n }\n};\n\n// The TooltipHost root uses display: inline by default.\n// To prevent sizing issues or tooltip positioning issues, we override to inline-block.\n// For more details see \"Icon Button with Tooltip\" on https://developer.microsoft.com/en-us/fluentui#/controls/web/button\nconst hostStyles: Partial<ITooltipHostStyles> = { root: { display: 'inline-block' } };\n\nconst MemoMessageStatusIcon = React.memo((obj: MessageStatusIconProps): JSX.Element => {\n return <MessageStatusIcon {...obj} />;\n});\n"]}
|
1
|
+
{"version":3,"file":"MessageStatusIndicatorInternal.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/MessageStatusIndicatorInternal.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { ICalloutContentStyles, ITooltipHostStyles, mergeStyles, TooltipHost } from '@fluentui/react';\nimport { MessageStatus, _formatString } from '@internal/acs-ui-common';\nimport React, { useState } from 'react';\nimport { useLocale } from '../localization';\nimport { useTheme } from '../theming';\nimport { isDarkThemed } from '../theming/themeUtils';\nimport { BaseCustomStyles } from '../types';\nimport {\n MessageStatusIndicatorErrorIconStyle,\n MessageStatusIndicatorIconStyle\n} from './styles/MessageStatusIndicator.styles';\nimport { MessageStatusIndicatorStrings } from './MessageStatusIndicator';\nimport { MessageStatusIcon, MessageStatusIconProps } from './MessageStatusIcon';\n\n/**\n * Props for {@link MessageStatusIndicatorInternal}.\n *\n * @internal\n */\nexport interface MessageStatusIndicatorInternalProps {\n /** Message status that determines the icon to display. */\n status?: MessageStatus;\n readCount?: number;\n onToggleToolTip?: (isToggled: boolean) => void;\n /** number of participants not including myself */\n remoteParticipantsCount?: number;\n /**\n * Allows users to pass an object containing custom CSS styles.\n * @Example\n * ```\n * <MessageStatus styles={{ root: { background: 'blue' } }} />\n * ```\n */\n styles?: BaseCustomStyles;\n /**\n * Optional strings to override in component\n */\n strings?: MessageStatusIndicatorStrings;\n /**\n * Optional call back to provide LiveMessage component for accessibility\n */\n shouldAnnounce: boolean;\n}\n\n/**\n * Component to display the status of a sent message.\n *\n * Adds an icon and tooltip corresponding to the message status.\n *\n * @internal\n */\nexport const MessageStatusIndicatorInternal = (props: MessageStatusIndicatorInternalProps): JSX.Element => {\n const { status, styles, remoteParticipantsCount, onToggleToolTip, readCount, shouldAnnounce } = props;\n const localeStrings = useLocale().strings.messageStatusIndicator;\n const [isTooltipToggled, setIsTooltipToggled] = useState<boolean>(false);\n const strings = { ...localeStrings, ...props.strings };\n const theme = useTheme();\n\n const calloutStyle: Partial<ICalloutContentStyles> = { root: { padding: 0 }, calloutMain: { padding: '0.5rem' } };\n\n // Place callout with no gap between it and the button.\n const calloutProps = {\n gapSpace: 0,\n styles: calloutStyle,\n backgroundColor: isDarkThemed(theme) ? theme.palette.neutralLighter : ''\n };\n\n switch (status) {\n case 'failed':\n return (\n <TooltipHost\n content={strings.failedToSendTooltipText}\n data-ui-id=\"chat-composite-message-tooltip\"\n calloutProps={{ ...calloutProps }}\n styles={hostStyles}\n >\n <MemoMessageStatusIcon\n shouldAnnounce={shouldAnnounce}\n iconName=\"MessageFailed\"\n iconClassName={mergeStyles(\n MessageStatusIndicatorErrorIconStyle,\n { color: isDarkThemed(theme) ? theme.semanticColors.errorText : theme.palette.redDark },\n styles?.root\n )}\n ariaLabel={strings.failedToSendAriaLabel}\n />\n </TooltipHost>\n );\n case 'sending':\n return (\n <TooltipHost\n content={strings.sendingTooltipText}\n data-ui-id=\"chat-composite-message-tooltip\"\n calloutProps={{ ...calloutProps }}\n styles={hostStyles}\n >\n <MemoMessageStatusIcon\n shouldAnnounce={shouldAnnounce}\n iconName=\"MessageSending\"\n iconClassName={mergeStyles(\n MessageStatusIndicatorIconStyle,\n { color: theme.palette.themePrimary },\n styles?.root\n )}\n ariaLabel={strings.sendingAriaLabel}\n />\n </TooltipHost>\n );\n case 'seen':\n return (\n <TooltipHost\n calloutProps={{ ...calloutProps }}\n data-ui-id=\"chat-composite-message-tooltip\"\n styles={hostStyles}\n content={\n // when it's just 1 to 1 texting, we don't need to know who has read the message, just show message as 'seen'\n // when readCount is 0, we have a bug, show 'seen' to cover up as a fall back\n // when participant count is 0, we have a bug, show 'seen' to cover up as a fall back\n readCount === 0 ||\n (remoteParticipantsCount && remoteParticipantsCount <= 1) ||\n !readCount ||\n !remoteParticipantsCount ||\n strings.readByTooltipText === undefined\n ? strings.seenTooltipText\n : _formatString(strings.readByTooltipText, {\n messageThreadReadCount: `${readCount}`,\n remoteParticipantsCount: `${remoteParticipantsCount}`\n })\n }\n onTooltipToggle={() => {\n if (onToggleToolTip) {\n onToggleToolTip(!isTooltipToggled);\n setIsTooltipToggled(!isTooltipToggled);\n }\n }}\n >\n <MemoMessageStatusIcon\n shouldAnnounce={shouldAnnounce}\n iconName=\"MessageSeen\"\n iconClassName={mergeStyles({ color: theme.palette.themePrimary }, styles?.root)}\n ariaLabel={strings.seenAriaLabel}\n />\n </TooltipHost>\n );\n case 'delivered':\n return (\n <TooltipHost\n calloutProps={{ ...calloutProps }}\n content={strings.deliveredTooltipText}\n data-ui-id=\"chat-composite-message-tooltip\"\n styles={hostStyles}\n >\n <MemoMessageStatusIcon\n shouldAnnounce={shouldAnnounce}\n iconName=\"MessageDelivered\"\n iconClassName={mergeStyles(\n MessageStatusIndicatorIconStyle,\n { color: theme.palette.themePrimary },\n styles?.root\n )}\n ariaLabel={strings.deliveredAriaLabel}\n />\n </TooltipHost>\n );\n default:\n return <></>;\n }\n};\n\n// The TooltipHost root uses display: inline by default.\n// To prevent sizing issues or tooltip positioning issues, we override to inline-block.\n// For more details see \"Icon Button with Tooltip\" on https://developer.microsoft.com/en-us/fluentui#/controls/web/button\nconst hostStyles: Partial<ITooltipHostStyles> = { root: { display: 'inline-block' } };\n\nconst MemoMessageStatusIcon = React.memo((obj: MessageStatusIconProps): JSX.Element => {\n return <MessageStatusIcon {...obj} />;\n});\n"]}
|
@@ -23,7 +23,7 @@ export interface NotificationStackProps {
|
|
23
23
|
* Use this to control notifications shown when they dismissed by the user.
|
24
24
|
* Note this onDismiss function will affect all notifications in the same stack
|
25
25
|
*/
|
26
|
-
onDismissNotification?: (
|
26
|
+
onDismissNotification?: (dismissedNotification: ActiveNotification) => void;
|
27
27
|
/**
|
28
28
|
* If set, notifications with {@link ActiveNotification.timestamp} older than the time this component is mounted
|
29
29
|
* are not shown.
|
@@ -44,94 +44,94 @@ export interface NotificationStackStrings {
|
|
44
44
|
/**
|
45
45
|
* A generic message when starting video fails.
|
46
46
|
*/
|
47
|
-
startVideoGeneric
|
47
|
+
startVideoGeneric?: NotificationStrings;
|
48
48
|
/**
|
49
49
|
* A generic message when starting video fails.
|
50
50
|
*/
|
51
|
-
stopVideoGeneric
|
51
|
+
stopVideoGeneric?: NotificationStrings;
|
52
52
|
/**
|
53
53
|
* A generic message when muting microphone fails.
|
54
54
|
*/
|
55
|
-
muteGeneric
|
55
|
+
muteGeneric?: NotificationStrings;
|
56
56
|
/**
|
57
57
|
* A generic message when unmuting microphone fails.
|
58
58
|
*/
|
59
|
-
unmuteGeneric
|
59
|
+
unmuteGeneric?: NotificationStrings;
|
60
60
|
/**
|
61
61
|
* A generic message when starting screenshare fails.
|
62
62
|
*/
|
63
|
-
startScreenShareGeneric
|
63
|
+
startScreenShareGeneric?: NotificationStrings;
|
64
64
|
/**
|
65
65
|
* A generic message when stopping screenshare fails.
|
66
66
|
*/
|
67
|
-
stopScreenShareGeneric
|
67
|
+
stopScreenShareGeneric?: NotificationStrings;
|
68
68
|
/**
|
69
69
|
* Message shown when poor network quality is detected during a call.
|
70
70
|
*/
|
71
|
-
callNetworkQualityLow
|
71
|
+
callNetworkQualityLow?: NotificationStrings;
|
72
72
|
/**
|
73
73
|
* Message shown on failure to detect audio output devices.
|
74
74
|
*/
|
75
|
-
callNoSpeakerFound
|
75
|
+
callNoSpeakerFound?: NotificationStrings;
|
76
76
|
/**
|
77
77
|
* Message shown on failure to detect audio input devices.
|
78
78
|
*/
|
79
|
-
callNoMicrophoneFound
|
79
|
+
callNoMicrophoneFound?: NotificationStrings;
|
80
80
|
/**
|
81
81
|
* Message shown when microphone can be enumerated but access is blocked by the system.
|
82
82
|
*/
|
83
|
-
callMicrophoneAccessDenied
|
83
|
+
callMicrophoneAccessDenied?: NotificationStrings;
|
84
84
|
/**
|
85
85
|
* Message shown when microphone can be enumerated but access is blocked by the system, for safari browsers
|
86
86
|
*/
|
87
|
-
callMicrophoneAccessDeniedSafari
|
87
|
+
callMicrophoneAccessDeniedSafari?: NotificationStrings;
|
88
88
|
/**
|
89
89
|
* Message shown when microphone is muted by the system (not by local or remote participants)
|
90
90
|
*/
|
91
|
-
callMicrophoneMutedBySystem
|
91
|
+
callMicrophoneMutedBySystem?: NotificationStrings;
|
92
92
|
/**
|
93
93
|
* Message shown when microphone is unmuted by the system (not by local or remote participants).
|
94
94
|
* This typically occurs if the system recovers from an unexpected mute.
|
95
95
|
*/
|
96
|
-
callMicrophoneUnmutedBySystem
|
96
|
+
callMicrophoneUnmutedBySystem?: NotificationStrings;
|
97
97
|
/**
|
98
98
|
* Mac OS specific message shown when microphone can be enumerated but access is
|
99
99
|
* blocked by the system.
|
100
100
|
*/
|
101
|
-
callMacOsMicrophoneAccessDenied
|
101
|
+
callMacOsMicrophoneAccessDenied?: NotificationStrings;
|
102
102
|
/**
|
103
103
|
* Message shown when poor network causes local video stream to be frozen.
|
104
104
|
*/
|
105
|
-
callLocalVideoFreeze
|
105
|
+
callLocalVideoFreeze?: NotificationStrings;
|
106
106
|
/**
|
107
107
|
* Message shown when camera can be enumerated but access is blocked by the system.
|
108
108
|
*/
|
109
|
-
callCameraAccessDenied
|
109
|
+
callCameraAccessDenied?: NotificationStrings;
|
110
110
|
/**
|
111
111
|
* Message shown when camera can be enumerated but access is blocked by the system, for safari browsers
|
112
112
|
*/
|
113
|
-
callCameraAccessDeniedSafari
|
113
|
+
callCameraAccessDeniedSafari?: NotificationStrings;
|
114
114
|
/**
|
115
115
|
* Message shown when local video fails to start because camera is already in use by
|
116
116
|
* another applciation.
|
117
117
|
*/
|
118
|
-
callCameraAlreadyInUse
|
118
|
+
callCameraAlreadyInUse?: NotificationStrings;
|
119
119
|
/**
|
120
120
|
* Message shown when local video is stopped by the system (not by local or remote participants)
|
121
121
|
*/
|
122
|
-
callVideoStoppedBySystem
|
122
|
+
callVideoStoppedBySystem?: NotificationStrings;
|
123
123
|
/**
|
124
124
|
* Message shown when local video was recovered by the system (not by the local participant)
|
125
125
|
*/
|
126
|
-
callVideoRecoveredBySystem
|
126
|
+
callVideoRecoveredBySystem?: NotificationStrings;
|
127
127
|
/**
|
128
128
|
* Mac OS specific message shown when system denies access to camera.
|
129
129
|
*/
|
130
|
-
callMacOsCameraAccessDenied
|
130
|
+
callMacOsCameraAccessDenied?: NotificationStrings;
|
131
131
|
/**
|
132
132
|
* Mac OS specific message shown when system denies sharing local screen on a call.
|
133
133
|
*/
|
134
|
-
callMacOsScreenShareAccessDenied
|
134
|
+
callMacOsScreenShareAccessDenied?: NotificationStrings;
|
135
135
|
/**
|
136
136
|
* Dimiss Notifications button aria label read by screen reader accessibility tools
|
137
137
|
*/
|
@@ -155,15 +155,47 @@ export interface NotificationStackStrings {
|
|
155
155
|
/**
|
156
156
|
* An error message when starting spotlight while max participants are spotlighted
|
157
157
|
*/
|
158
|
-
startSpotlightWhileMaxParticipantsAreSpotlighted
|
158
|
+
startSpotlightWhileMaxParticipantsAreSpotlighted?: NotificationStrings;
|
159
159
|
/**
|
160
160
|
* Muted by a remote participant message
|
161
161
|
*/
|
162
|
-
mutedByRemoteParticipant
|
162
|
+
mutedByRemoteParticipant?: NotificationStrings;
|
163
163
|
/**
|
164
164
|
* Speaking while muted message
|
165
165
|
*/
|
166
|
-
speakingWhileMuted
|
166
|
+
speakingWhileMuted?: NotificationStrings;
|
167
|
+
/**
|
168
|
+
* Recording started message
|
169
|
+
*/
|
170
|
+
recordingStarted?: NotificationStrings;
|
171
|
+
/**
|
172
|
+
* Transcription started message
|
173
|
+
*/
|
174
|
+
transcriptionStarted?: NotificationStrings;
|
175
|
+
/**
|
176
|
+
* Recording stopped message
|
177
|
+
*/
|
178
|
+
recordingStopped?: NotificationStrings;
|
179
|
+
/**
|
180
|
+
* Transcription stopped message
|
181
|
+
*/
|
182
|
+
transcriptionStopped?: NotificationStrings;
|
183
|
+
/**
|
184
|
+
* Recording and transcription both started message
|
185
|
+
*/
|
186
|
+
recordingAndTranscriptionStarted?: NotificationStrings;
|
187
|
+
/**
|
188
|
+
* Recording and transcription both stopped message
|
189
|
+
*/
|
190
|
+
recordingAndTranscriptionStopped?: NotificationStrings;
|
191
|
+
/**
|
192
|
+
* Recording stopped but transcription still going on message
|
193
|
+
*/
|
194
|
+
recordingStoppedStillTranscribing?: NotificationStrings;
|
195
|
+
/**
|
196
|
+
* Transcription stopped but recording still going on message
|
197
|
+
*/
|
198
|
+
transcriptionStoppedStillRecording?: NotificationStrings;
|
167
199
|
}
|
168
200
|
/**
|
169
201
|
* All notifications that can be shown in the {@link NotificationStack}.
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"NotificationStack.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/NotificationStack.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport React, { useEffect, useRef, useState } from 'react';\nimport { Stack } from '@fluentui/react';\n/* @conditional-compile-remove(notifications) */\nimport { useLocale } from '../localization';\nimport {\n DismissedNotification,\n NotificationIconProps,\n dismissNotification,\n dropDismissalsForInactiveNotifications,\n notificationsToShow\n} from './utils';\nimport { Notification, NotificationStrings } from './Notification';\n\n/**\n * Props for {@link NotificationStack}.\n * @beta\n */\nexport interface NotificationStackProps {\n /**\n * Strings shown on the UI on errors.\n */\n strings?: NotificationStackStrings;\n\n /**\n * Currently active notifications.\n */\n activeNotifications: ActiveNotification[];\n\n /**\n * Max notifications to show at a time.\n * @defaultValue 2\n */\n maxNotificationsToShow?: number;\n\n /**\n * Callback called when the dismiss button is triggered.\n * Use this to control notifications shown when they dismissed by the user.\n * Note this onDismiss function will affect all notifications in the same stack\n */\n onDismissNotification?: (dismissedNotifications: ActiveNotification) => void;\n\n /**\n * If set, notifications with {@link ActiveNotification.timestamp} older than the time this component is mounted\n * are not shown.\n *\n * This is useful when using the {@link NotificationStack} with a stateful client that handles more than one call\n * or chat thread. Set this prop to ignore notifications from previous call or chat.\n *\n * @defaultValue false\n */\n ignorePremountNotifications?: boolean;\n}\n\n/**\n * All strings that may be shown on the UI in the {@link NotificationStack}.\n *\n * @beta\n */\nexport interface NotificationStackStrings {\n /**\n * A generic message when starting video fails.\n */\n startVideoGeneric: NotificationStrings;\n\n /**\n * A generic message when starting video fails.\n */\n stopVideoGeneric: NotificationStrings;\n\n /**\n * A generic message when muting microphone fails.\n */\n muteGeneric: NotificationStrings;\n\n /**\n * A generic message when unmuting microphone fails.\n */\n unmuteGeneric: NotificationStrings;\n\n /**\n * A generic message when starting screenshare fails.\n */\n startScreenShareGeneric: NotificationStrings;\n\n /**\n * A generic message when stopping screenshare fails.\n */\n stopScreenShareGeneric: NotificationStrings;\n\n /**\n * Message shown when poor network quality is detected during a call.\n */\n callNetworkQualityLow: NotificationStrings;\n\n /**\n * Message shown on failure to detect audio output devices.\n */\n callNoSpeakerFound: NotificationStrings;\n\n /**\n * Message shown on failure to detect audio input devices.\n */\n callNoMicrophoneFound: NotificationStrings;\n\n /**\n * Message shown when microphone can be enumerated but access is blocked by the system.\n */\n callMicrophoneAccessDenied: NotificationStrings;\n\n /**\n * Message shown when microphone can be enumerated but access is blocked by the system, for safari browsers\n */\n callMicrophoneAccessDeniedSafari: NotificationStrings;\n\n /**\n * Message shown when microphone is muted by the system (not by local or remote participants)\n */\n callMicrophoneMutedBySystem: NotificationStrings;\n\n /**\n * Message shown when microphone is unmuted by the system (not by local or remote participants).\n * This typically occurs if the system recovers from an unexpected mute.\n */\n callMicrophoneUnmutedBySystem: NotificationStrings;\n\n /**\n * Mac OS specific message shown when microphone can be enumerated but access is\n * blocked by the system.\n */\n callMacOsMicrophoneAccessDenied: NotificationStrings;\n\n /**\n * Message shown when poor network causes local video stream to be frozen.\n */\n callLocalVideoFreeze: NotificationStrings;\n\n /**\n * Message shown when camera can be enumerated but access is blocked by the system.\n */\n callCameraAccessDenied: NotificationStrings;\n\n /**\n * Message shown when camera can be enumerated but access is blocked by the system, for safari browsers\n */\n callCameraAccessDeniedSafari: NotificationStrings;\n\n /**\n * Message shown when local video fails to start because camera is already in use by\n * another applciation.\n */\n callCameraAlreadyInUse: NotificationStrings;\n\n /**\n * Message shown when local video is stopped by the system (not by local or remote participants)\n */\n callVideoStoppedBySystem: NotificationStrings;\n\n /**\n * Message shown when local video was recovered by the system (not by the local participant)\n */\n callVideoRecoveredBySystem: NotificationStrings;\n\n /**\n * Mac OS specific message shown when system denies access to camera.\n */\n callMacOsCameraAccessDenied: NotificationStrings;\n\n /**\n * Mac OS specific message shown when system denies sharing local screen on a call.\n */\n callMacOsScreenShareAccessDenied: NotificationStrings;\n\n /**\n * Dimiss Notifications button aria label read by screen reader accessibility tools\n */\n dismissButtonAriaLabel?: NotificationStrings;\n\n /**\n * An error message when joining a call fails.\n */\n failedToJoinCallGeneric?: NotificationStrings;\n\n /**\n * An error message when joining a call fails specifically due to an invalid meeting link.\n */\n failedToJoinCallInvalidMeetingLink?: NotificationStrings;\n /**\n * Error string letting you know remote participants see a frozen stream for you.\n */\n cameraFrozenForRemoteParticipants?: NotificationStrings;\n\n /**\n * Unable to start effect\n */\n unableToStartVideoEffect?: NotificationStrings;\n /**\n * An error message when starting spotlight while max participants are spotlighted\n */\n startSpotlightWhileMaxParticipantsAreSpotlighted: NotificationStrings;\n /* @conditional-compile-remove(soft-mute) */\n /**\n * Muted by a remote participant message\n */\n mutedByRemoteParticipant: NotificationStrings;\n /**\n * Speaking while muted message\n */\n speakingWhileMuted: NotificationStrings;\n}\n\n/**\n * All notifications that can be shown in the {@link NotificationStack}.\n *\n * @beta\n */\nexport type NotificationType = keyof NotificationStackStrings;\n\n/**\n * Active notifications to be shown via {@link NotificationStack}.\n *\n * @beta\n */\nexport interface ActiveNotification {\n /**\n * Type of error that is active.\n */\n type: NotificationType;\n /**\n * Callback called when the primary button inside notification bar is clicked.\n */\n onClickPrimaryButton?: () => void;\n\n /**\n * Callback called when the primary button inside notification bar is clicked.\n */\n onClickSecondaryButton?: () => void;\n\n /**\n * Callback called when the notification is dismissed.\n */\n onDismiss?: () => void;\n\n /**\n * If set, notification will automatically dismiss after 5 seconds\n */\n autoDismiss?: boolean;\n\n /**\n * The latest timestamp when this notification was observed.\n *\n * When available, this is used to track notifications that have already been seen and dismissed\n * by the user.\n */\n timestamp?: Date;\n}\n\n/**\n * A component to show notifications on the UI.\n * All strings that can be shown are accepted as the {@link NotificationStackProps.strings} so that they can be localized.\n * Active notifications are selected by {@link NotificationStackProps.activeNotifications}.\n *\n * This component internally tracks dismissed by the user.\n * * Notifications that have an associated timestamp: The notification is shown on the UI again if it occurs after being dismissed.\n * * Notifications that do not have a timestamp: The notification is dismissed until it disappears from the props.\n * If the notification recurs, it is shown in the UI.\n *\n *\n * @beta\n */\nexport const NotificationStack = (props: NotificationStackProps): JSX.Element => {\n /* @conditional-compile-remove(notifications) */\n const localeStrings = useLocale().strings.notificationStack;\n const strings = props.strings ?? /* @conditional-compile-remove(notifications) */ localeStrings;\n const maxNotificationsToShow = props.maxNotificationsToShow ?? 2;\n\n const trackDismissedNotificationsInternally = !props.onDismissNotification;\n\n // Timestamp for when this comopnent is first mounted.\n // Never updated through the lifecycle of this component.\n const mountTimestamp = useRef(new Date(Date.now()));\n\n const [dismissedNotifications, setDismissedNotifications] = useState<DismissedNotification[]>([]);\n\n // dropDismissalsForInactiveNotifications only returns a new object if `dismissedErrors` actually changes.\n // Without this behaviour, this `useEffect` block would cause a render loop.\n useEffect(() => {\n trackDismissedNotificationsInternally &&\n setDismissedNotifications(\n dropDismissalsForInactiveNotifications(props.activeNotifications, dismissedNotifications)\n );\n }, [props.activeNotifications, dismissedNotifications, trackDismissedNotificationsInternally]);\n\n const activeNotifications = notificationsToShow(\n props.activeNotifications,\n dismissedNotifications,\n props.ignorePremountNotifications ? mountTimestamp.current : undefined\n );\n\n return (\n <Stack\n data-ui-id=\"notifications-stack\"\n style={{\n width: 'fit-content'\n }}\n >\n {activeNotifications.map((notification, index) => {\n if (index < maxNotificationsToShow) {\n return (\n <div key={index} style={{ marginBottom: `${index === maxNotificationsToShow - 1 ? 0 : '0.25rem'}` }}>\n <Notification\n notificationStrings={strings ? strings[notification.type] : undefined}\n notificationIconProps={NotificationIconProps(notification.type)}\n onClickPrimaryButton={() => notification.onClickPrimaryButton?.()}\n onClickSecondaryButton={() => notification.onClickSecondaryButton?.()}\n onDismiss={() => {\n trackDismissedNotificationsInternally\n ? setDismissedNotifications(dismissNotification(dismissedNotifications, notification))\n : props.onDismissNotification?.(notification);\n notification.onDismiss && notification.onDismiss();\n }}\n showStackedEffect={\n index === maxNotificationsToShow - 1 && activeNotifications.length > maxNotificationsToShow\n }\n autoDismiss={notification.autoDismiss}\n />\n </div>\n );\n } else {\n return <></>;\n }\n })}\n </Stack>\n );\n};\n"]}
|
1
|
+
{"version":3,"file":"NotificationStack.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/NotificationStack.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport React, { useEffect, useRef, useState } from 'react';\nimport { Stack } from '@fluentui/react';\n/* @conditional-compile-remove(notifications) */\nimport { useLocale } from '../localization';\nimport {\n DismissedNotification,\n NotificationIconProps,\n dismissNotification,\n dropDismissalsForInactiveNotifications,\n notificationsToShow\n} from './utils';\nimport { Notification, NotificationStrings } from './Notification';\n\n/**\n * Props for {@link NotificationStack}.\n * @beta\n */\nexport interface NotificationStackProps {\n /**\n * Strings shown on the UI on errors.\n */\n strings?: NotificationStackStrings;\n\n /**\n * Currently active notifications.\n */\n activeNotifications: ActiveNotification[];\n\n /**\n * Max notifications to show at a time.\n * @defaultValue 2\n */\n maxNotificationsToShow?: number;\n\n /**\n * Callback called when the dismiss button is triggered.\n * Use this to control notifications shown when they dismissed by the user.\n * Note this onDismiss function will affect all notifications in the same stack\n */\n onDismissNotification?: (dismissedNotification: ActiveNotification) => void;\n\n /**\n * If set, notifications with {@link ActiveNotification.timestamp} older than the time this component is mounted\n * are not shown.\n *\n * This is useful when using the {@link NotificationStack} with a stateful client that handles more than one call\n * or chat thread. Set this prop to ignore notifications from previous call or chat.\n *\n * @defaultValue false\n */\n ignorePremountNotifications?: boolean;\n}\n\n/**\n * All strings that may be shown on the UI in the {@link NotificationStack}.\n *\n * @beta\n */\nexport interface NotificationStackStrings {\n /**\n * A generic message when starting video fails.\n */\n startVideoGeneric?: NotificationStrings;\n\n /**\n * A generic message when starting video fails.\n */\n stopVideoGeneric?: NotificationStrings;\n\n /**\n * A generic message when muting microphone fails.\n */\n muteGeneric?: NotificationStrings;\n\n /**\n * A generic message when unmuting microphone fails.\n */\n unmuteGeneric?: NotificationStrings;\n\n /**\n * A generic message when starting screenshare fails.\n */\n startScreenShareGeneric?: NotificationStrings;\n\n /**\n * A generic message when stopping screenshare fails.\n */\n stopScreenShareGeneric?: NotificationStrings;\n\n /**\n * Message shown when poor network quality is detected during a call.\n */\n callNetworkQualityLow?: NotificationStrings;\n\n /**\n * Message shown on failure to detect audio output devices.\n */\n callNoSpeakerFound?: NotificationStrings;\n\n /**\n * Message shown on failure to detect audio input devices.\n */\n callNoMicrophoneFound?: NotificationStrings;\n\n /**\n * Message shown when microphone can be enumerated but access is blocked by the system.\n */\n callMicrophoneAccessDenied?: NotificationStrings;\n\n /**\n * Message shown when microphone can be enumerated but access is blocked by the system, for safari browsers\n */\n callMicrophoneAccessDeniedSafari?: NotificationStrings;\n\n /**\n * Message shown when microphone is muted by the system (not by local or remote participants)\n */\n callMicrophoneMutedBySystem?: NotificationStrings;\n\n /**\n * Message shown when microphone is unmuted by the system (not by local or remote participants).\n * This typically occurs if the system recovers from an unexpected mute.\n */\n callMicrophoneUnmutedBySystem?: NotificationStrings;\n\n /**\n * Mac OS specific message shown when microphone can be enumerated but access is\n * blocked by the system.\n */\n callMacOsMicrophoneAccessDenied?: NotificationStrings;\n\n /**\n * Message shown when poor network causes local video stream to be frozen.\n */\n callLocalVideoFreeze?: NotificationStrings;\n\n /**\n * Message shown when camera can be enumerated but access is blocked by the system.\n */\n callCameraAccessDenied?: NotificationStrings;\n\n /**\n * Message shown when camera can be enumerated but access is blocked by the system, for safari browsers\n */\n callCameraAccessDeniedSafari?: NotificationStrings;\n\n /**\n * Message shown when local video fails to start because camera is already in use by\n * another applciation.\n */\n callCameraAlreadyInUse?: NotificationStrings;\n\n /**\n * Message shown when local video is stopped by the system (not by local or remote participants)\n */\n callVideoStoppedBySystem?: NotificationStrings;\n\n /**\n * Message shown when local video was recovered by the system (not by the local participant)\n */\n callVideoRecoveredBySystem?: NotificationStrings;\n\n /**\n * Mac OS specific message shown when system denies access to camera.\n */\n callMacOsCameraAccessDenied?: NotificationStrings;\n\n /**\n * Mac OS specific message shown when system denies sharing local screen on a call.\n */\n callMacOsScreenShareAccessDenied?: NotificationStrings;\n\n /**\n * Dimiss Notifications button aria label read by screen reader accessibility tools\n */\n dismissButtonAriaLabel?: NotificationStrings;\n\n /**\n * An error message when joining a call fails.\n */\n failedToJoinCallGeneric?: NotificationStrings;\n\n /**\n * An error message when joining a call fails specifically due to an invalid meeting link.\n */\n failedToJoinCallInvalidMeetingLink?: NotificationStrings;\n /**\n * Error string letting you know remote participants see a frozen stream for you.\n */\n cameraFrozenForRemoteParticipants?: NotificationStrings;\n\n /**\n * Unable to start effect\n */\n unableToStartVideoEffect?: NotificationStrings;\n /**\n * An error message when starting spotlight while max participants are spotlighted\n */\n startSpotlightWhileMaxParticipantsAreSpotlighted?: NotificationStrings;\n /* @conditional-compile-remove(soft-mute) */\n /**\n * Muted by a remote participant message\n */\n mutedByRemoteParticipant?: NotificationStrings;\n /**\n * Speaking while muted message\n */\n speakingWhileMuted?: NotificationStrings;\n /**\n * Recording started message\n */\n recordingStarted?: NotificationStrings;\n /**\n * Transcription started message\n */\n transcriptionStarted?: NotificationStrings;\n /**\n * Recording stopped message\n */\n recordingStopped?: NotificationStrings;\n /**\n * Transcription stopped message\n */\n transcriptionStopped?: NotificationStrings;\n /**\n * Recording and transcription both started message\n */\n recordingAndTranscriptionStarted?: NotificationStrings;\n /**\n * Recording and transcription both stopped message\n */\n recordingAndTranscriptionStopped?: NotificationStrings;\n /**\n * Recording stopped but transcription still going on message\n */\n recordingStoppedStillTranscribing?: NotificationStrings;\n /**\n * Transcription stopped but recording still going on message\n */\n transcriptionStoppedStillRecording?: NotificationStrings;\n}\n\n/**\n * All notifications that can be shown in the {@link NotificationStack}.\n *\n * @beta\n */\nexport type NotificationType = keyof NotificationStackStrings;\n\n/**\n * Active notifications to be shown via {@link NotificationStack}.\n *\n * @beta\n */\nexport interface ActiveNotification {\n /**\n * Type of error that is active.\n */\n type: NotificationType;\n /**\n * Callback called when the primary button inside notification bar is clicked.\n */\n onClickPrimaryButton?: () => void;\n\n /**\n * Callback called when the primary button inside notification bar is clicked.\n */\n onClickSecondaryButton?: () => void;\n\n /**\n * Callback called when the notification is dismissed.\n */\n onDismiss?: () => void;\n\n /**\n * If set, notification will automatically dismiss after 5 seconds\n */\n autoDismiss?: boolean;\n\n /**\n * The latest timestamp when this notification was observed.\n *\n * When available, this is used to track notifications that have already been seen and dismissed\n * by the user.\n */\n timestamp?: Date;\n}\n\n/**\n * A component to show notifications on the UI.\n * All strings that can be shown are accepted as the {@link NotificationStackProps.strings} so that they can be localized.\n * Active notifications are selected by {@link NotificationStackProps.activeNotifications}.\n *\n * This component internally tracks dismissed by the user.\n * * Notifications that have an associated timestamp: The notification is shown on the UI again if it occurs after being dismissed.\n * * Notifications that do not have a timestamp: The notification is dismissed until it disappears from the props.\n * If the notification recurs, it is shown in the UI.\n *\n *\n * @beta\n */\nexport const NotificationStack = (props: NotificationStackProps): JSX.Element => {\n /* @conditional-compile-remove(notifications) */\n const localeStrings = useLocale().strings.notificationStack;\n const strings = props.strings ?? /* @conditional-compile-remove(notifications) */ localeStrings;\n const maxNotificationsToShow = props.maxNotificationsToShow ?? 2;\n\n const trackDismissedNotificationsInternally = !props.onDismissNotification;\n\n // Timestamp for when this comopnent is first mounted.\n // Never updated through the lifecycle of this component.\n const mountTimestamp = useRef(new Date(Date.now()));\n\n const [dismissedNotifications, setDismissedNotifications] = useState<DismissedNotification[]>([]);\n\n // dropDismissalsForInactiveNotifications only returns a new object if `dismissedErrors` actually changes.\n // Without this behaviour, this `useEffect` block would cause a render loop.\n useEffect(() => {\n trackDismissedNotificationsInternally &&\n setDismissedNotifications(\n dropDismissalsForInactiveNotifications(props.activeNotifications, dismissedNotifications)\n );\n }, [props.activeNotifications, dismissedNotifications, trackDismissedNotificationsInternally]);\n\n const activeNotifications = notificationsToShow(\n props.activeNotifications,\n dismissedNotifications,\n props.ignorePremountNotifications ? mountTimestamp.current : undefined\n );\n\n return (\n <Stack\n data-ui-id=\"notifications-stack\"\n style={{\n width: 'fit-content'\n }}\n >\n {activeNotifications.map((notification, index) => {\n if (index < maxNotificationsToShow) {\n return (\n <div key={index} style={{ marginBottom: `${index === maxNotificationsToShow - 1 ? 0 : '0.25rem'}` }}>\n <Notification\n notificationStrings={strings ? strings[notification.type] : undefined}\n notificationIconProps={NotificationIconProps(notification.type)}\n onClickPrimaryButton={() => notification.onClickPrimaryButton?.()}\n onClickSecondaryButton={() => notification.onClickSecondaryButton?.()}\n onDismiss={() => {\n trackDismissedNotificationsInternally\n ? setDismissedNotifications(dismissNotification(dismissedNotifications, notification))\n : props.onDismissNotification?.(notification);\n notification.onDismiss && notification.onDismiss();\n }}\n showStackedEffect={\n index === maxNotificationsToShow - 1 && activeNotifications.length > maxNotificationsToShow\n }\n autoDismiss={notification.autoDismiss}\n />\n </div>\n );\n } else {\n return <></>;\n }\n })}\n </Stack>\n );\n};\n"]}
|
package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/CopyPastePlugin.d.ts
CHANGED
@@ -7,11 +7,17 @@ export default class CopyPastePlugin implements EditorPlugin {
|
|
7
7
|
onPaste?: (event: {
|
8
8
|
content: DocumentFragment;
|
9
9
|
}) => void;
|
10
|
+
onUploadInlineImage?: (imageUrl: string, imageFileName: string) => void;
|
10
11
|
getName(): string;
|
11
12
|
initialize(editor: IEditor): void;
|
12
13
|
dispose(): void;
|
13
14
|
onPluginEvent(event: PluginEvent): void;
|
14
15
|
}
|
16
|
+
/**
|
17
|
+
* @internal
|
18
|
+
* Exported only for unit testing
|
19
|
+
*/
|
20
|
+
export declare const handleInlineImage: (event: PluginEvent, onUploadInlineImage?: (image: string, fileName: string) => void) => void;
|
15
21
|
/**
|
16
22
|
* @internal
|
17
23
|
* Exported only for unit testing
|
package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/CopyPastePlugin.js
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
import { ContentChangedEventSource, PluginEventType } from '../../utils/RichTextEditorUtils';
|
2
|
+
/* @conditional-compile-remove(rich-text-editor-image-upload) */
|
3
|
+
import { _base64ToBlob } from "../../../../../acs-ui-common/src";
|
2
4
|
/**
|
3
5
|
* CopyPastePlugin is a plugin for handling copy and paste events in the editor.
|
4
6
|
*/
|
@@ -15,6 +17,8 @@ export default class CopyPastePlugin {
|
|
15
17
|
dispose() { }
|
16
18
|
onPluginEvent(event) {
|
17
19
|
handleBeforePasteEvent(event, /* @conditional-compile-remove(rich-text-editor-image-upload) */ this.onPaste);
|
20
|
+
/* @conditional-compile-remove(rich-text-editor-image-upload) */
|
21
|
+
handleInlineImage(event, this.onUploadInlineImage);
|
18
22
|
if (this.editor !== null && !this.editor.isDisposed()) {
|
19
23
|
// scroll the editor to the correct position after pasting content
|
20
24
|
scrollToBottomAfterContentPaste(event);
|
@@ -33,12 +37,34 @@ const handleBeforePasteEvent = (event,
|
|
33
37
|
removeImageElement(event);
|
34
38
|
}
|
35
39
|
};
|
40
|
+
/* @conditional-compile-remove(rich-text-editor-image-upload) */
|
41
|
+
/**
|
42
|
+
* @internal
|
43
|
+
* Exported only for unit testing
|
44
|
+
*/
|
45
|
+
export const handleInlineImage = (event, onUploadInlineImage) => {
|
46
|
+
if (event.eventType === PluginEventType.BeforePaste && event.pasteType === 'normal' && onUploadInlineImage) {
|
47
|
+
event.fragment.querySelectorAll('img').forEach((image) => {
|
48
|
+
const clipboardImage = event.clipboardData.image;
|
49
|
+
const fileName = (clipboardImage === null || clipboardImage === void 0 ? void 0 : clipboardImage.name) || (clipboardImage === null || clipboardImage === void 0 ? void 0 : clipboardImage.type.replace('/', '.')) || 'image.png';
|
50
|
+
// If the image src is an external url, call the onUploadInlineImage callback with the url.
|
51
|
+
let imageUrl = image.src;
|
52
|
+
if (image.src.startsWith('data:image/')) {
|
53
|
+
const blobImage = _base64ToBlob(image.src);
|
54
|
+
imageUrl = URL.createObjectURL(blobImage);
|
55
|
+
}
|
56
|
+
onUploadInlineImage(imageUrl, fileName);
|
57
|
+
image.src = imageUrl;
|
58
|
+
image.alt = image.alt || 'image';
|
59
|
+
image.style.width = '119px'; // TODO: find a way to get the original width and height of the image
|
60
|
+
});
|
61
|
+
}
|
62
|
+
};
|
36
63
|
/**
|
37
64
|
* @internal
|
38
65
|
* Exported only for unit testing
|
39
66
|
*/
|
40
67
|
export const removeImageElement = (event) => {
|
41
|
-
// We don't support the pasting options such as paste as image yet.
|
42
68
|
if (event.pasteType === 'normal') {
|
43
69
|
event.fragment.querySelectorAll('img').forEach((image) => {
|
44
70
|
// If the image is the only child of its parent, remove all the parents of this img element.
|
package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/CopyPastePlugin.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"CopyPastePlugin.js","sourceRoot":"","sources":["../../../../../../../../react-components/src/components/RichTextEditor/Plugins/CopyPastePlugin.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;
|
1
|
+
{"version":3,"file":"CopyPastePlugin.js","sourceRoot":"","sources":["../../../../../../../../react-components/src/components/RichTextEditor/Plugins/CopyPastePlugin.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAC7F,gEAAgE;AAChE,OAAO,EAAE,aAAa,EAAE,yCAAgC;AAExD;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,eAAe;IAApC;QACU,WAAM,GAAmB,IAAI,CAAC;IA0BxC,CAAC;IAnBC,OAAO;QACL,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IAED,UAAU,CAAC,MAAe;QACxB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,OAAO,KAAU,CAAC;IAElB,aAAa,CAAC,KAAkB;QAC9B,sBAAsB,CAAC,KAAK,EAAE,gEAAgE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7G,gEAAgE;QAChE,iBAAiB,CAAC,KAAK,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC;QACnD,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC;YACtD,kEAAkE;YAClE,+BAA+B,CAAC,KAAK,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;CACF;AAED,MAAM,sBAAsB,GAAG,CAC7B,KAAkB;AAClB,gEAAgE,CAAC,OAEvD,EACJ,EAAE;IACR,IAAI,KAAK,CAAC,SAAS,KAAK,eAAe,CAAC,WAAW,IAAI,KAAK,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;QACpF,gEAAgE;QAChE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAG,EAAE,OAAO,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;QACvC,gEAAgE;QAChE,OAAO;QAEP,uBAAuB;QACvB,yGAAyG;QACzG,kBAAkB,CAAC,KAAyB,CAAC,CAAC;IAChD,CAAC;AACH,CAAC,CAAC;AAEF,gEAAgE;AAChE;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,KAAkB,EAClB,mBAA+D,EACzD,EAAE;IACR,IAAI,KAAK,CAAC,SAAS,KAAK,eAAe,CAAC,WAAW,IAAI,KAAK,CAAC,SAAS,KAAK,QAAQ,IAAI,mBAAmB,EAAE,CAAC;QAC3G,KAAK,CAAC,QAAQ,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACvD,MAAM,cAAc,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC;YACjD,MAAM,QAAQ,GAAG,CAAA,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,IAAI,MAAI,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA,IAAI,WAAW,CAAC;YAC/F,2FAA2F;YAC3F,IAAI,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC;YACzB,IAAI,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;gBACxC,MAAM,SAAS,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAC3C,QAAQ,GAAG,GAAG,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;YAC5C,CAAC;YAED,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAExC,KAAK,CAAC,GAAG,GAAG,QAAQ,CAAC;YACrB,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,OAAO,CAAC;YACjC,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,OAAO,CAAC,CAAC,qEAAqE;QACpG,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAAuB,EAAQ,EAAE;IAClE,IAAI,KAAK,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;QACjC,KAAK,CAAC,QAAQ,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACvD,4FAA4F;YAC5F,IAAI,UAAU,GAAuB,KAAK,CAAC,aAAa,CAAC;YACzD,IAAI,WAAW,GAAgB,KAAK,CAAC;YACrC,OAAO,CAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,UAAU,CAAC,MAAM,MAAK,CAAC,EAAE,CAAC;gBAC3C,WAAW,GAAG,UAAU,CAAC;gBACzB,UAAU,GAAG,UAAU,CAAC,aAAa,CAAC;YACxC,CAAC;YACD,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,MAAM,EAAE,CAAC;QACxB,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC,KAAkB,EAAQ,EAAE;IAC1E,IAAI,KAAK,CAAC,SAAS,KAAK,eAAe,CAAC,cAAc,IAAI,KAAK,CAAC,MAAM,KAAK,yBAAyB,CAAC,KAAK,EAAE,CAAC;QAC3G,4CAA4C;QAC5C,MAAM,SAAS,GAAG,QAAQ,CAAC,YAAY,EAAE,CAAC;QAE1C,4DAA4D;QAC5D,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,UAAU,IAAI,CAAC,EAAE,CAAC;YAC5C,8CAA8C;YAC9C,OAAO;QACT,CAAC;QAED,uCAAuC;QACvC,2FAA2F;QAC3F,MAAM,KAAK,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAEtC,wEAAwE;QACxE,0EAA0E;QAC1E,uGAAuG;QACvG,IAAI,KAAK,CAAC,uBAAuB,KAAK,QAAQ,EAAE,CAAC;YAC/C,OAAO;QACT,CAAC;QAED,oEAAoE;QACpE,wHAAwH;QACxH,MAAM,WAAW,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QACnD,sCAAsC;QACtC,yGAAyG;QACzG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACtB,gFAAgF;QAChF,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;QAE9B,yCAAyC;QACzC,8HAA8H;QAC9H,WAAW,CAAC,cAAc,CAAC;YACzB,KAAK,EAAE,QAAQ;SAChB,CAAC,CAAC;QACH,WAAW,CAAC,MAAM,EAAE,CAAC;IACvB,CAAC;AACH,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport type { PluginEvent, EditorPlugin, IEditor, BeforePasteEvent } from 'roosterjs-content-model-types';\nimport { ContentChangedEventSource, PluginEventType } from '../../utils/RichTextEditorUtils';\n/* @conditional-compile-remove(rich-text-editor-image-upload) */\nimport { _base64ToBlob } from '@internal/acs-ui-common';\n\n/**\n * CopyPastePlugin is a plugin for handling copy and paste events in the editor.\n */\nexport default class CopyPastePlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n // don't set value in constructor to be able to update it without plugin recreation\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n onPaste?: (event: { content: DocumentFragment }) => void;\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n onUploadInlineImage?: (imageUrl: string, imageFileName: string) => void;\n\n getName(): string {\n return 'CopyPastePlugin';\n }\n\n initialize(editor: IEditor): void {\n this.editor = editor;\n }\n\n dispose(): void {}\n\n onPluginEvent(event: PluginEvent): void {\n handleBeforePasteEvent(event, /* @conditional-compile-remove(rich-text-editor-image-upload) */ this.onPaste);\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n handleInlineImage(event, this.onUploadInlineImage);\n if (this.editor !== null && !this.editor.isDisposed()) {\n // scroll the editor to the correct position after pasting content\n scrollToBottomAfterContentPaste(event);\n }\n }\n}\n\nconst handleBeforePasteEvent = (\n event: PluginEvent,\n /* @conditional-compile-remove(rich-text-editor-image-upload) */ onPaste?: (event: {\n content: DocumentFragment;\n }) => void\n): void => {\n if (event.eventType === PluginEventType.BeforePaste && event.pasteType === 'normal') {\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n onPaste?.({ content: event.fragment });\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n return;\n\n // the initial behavior\n // removes inline image elements from the pasted content when rich-text-editor-image-upload not available\n removeImageElement(event as BeforePasteEvent);\n }\n};\n\n/* @conditional-compile-remove(rich-text-editor-image-upload) */\n/**\n * @internal\n * Exported only for unit testing\n */\nexport const handleInlineImage = (\n event: PluginEvent,\n onUploadInlineImage?: (image: string, fileName: string) => void\n): void => {\n if (event.eventType === PluginEventType.BeforePaste && event.pasteType === 'normal' && onUploadInlineImage) {\n event.fragment.querySelectorAll('img').forEach((image) => {\n const clipboardImage = event.clipboardData.image;\n const fileName = clipboardImage?.name || clipboardImage?.type.replace('/', '.') || 'image.png';\n // If the image src is an external url, call the onUploadInlineImage callback with the url.\n let imageUrl = image.src;\n if (image.src.startsWith('data:image/')) {\n const blobImage = _base64ToBlob(image.src);\n imageUrl = URL.createObjectURL(blobImage);\n }\n\n onUploadInlineImage(imageUrl, fileName);\n\n image.src = imageUrl;\n image.alt = image.alt || 'image';\n image.style.width = '119px'; // TODO: find a way to get the original width and height of the image\n });\n }\n};\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport const removeImageElement = (event: BeforePasteEvent): void => {\n if (event.pasteType === 'normal') {\n event.fragment.querySelectorAll('img').forEach((image) => {\n // If the image is the only child of its parent, remove all the parents of this img element.\n let parentNode: HTMLElement | null = image.parentElement;\n let currentNode: HTMLElement = image;\n while (parentNode?.childNodes.length === 1) {\n currentNode = parentNode;\n parentNode = parentNode.parentElement;\n }\n currentNode?.remove();\n });\n }\n};\n\n/**\n * Update the scroll position of the editor after pasting content to ensure the content is visible.\n * @param event - The plugin event.\n */\nexport const scrollToBottomAfterContentPaste = (event: PluginEvent): void => {\n if (event.eventType === PluginEventType.ContentChanged && event.source === ContentChangedEventSource.Paste) {\n // Get the current selection in the document\n const selection = document.getSelection();\n\n // Check if a selection exists and it has at least one range\n if (!selection || selection.rangeCount <= 0) {\n // If no selection or range, exit the function\n return;\n }\n\n // Get the first range of the selection\n // A user can normally only select one range at a time, so the rangeCount will usually be 1\n const range = selection.getRangeAt(0);\n\n // If the common ancestor container of the range is the document itself,\n // it might mean that the editable element is getting removed from the DOM\n // In such cases, especially in Safari, trying to modify the range might throw a HierarchyRequest error\n if (range.commonAncestorContainer === document) {\n return;\n }\n\n // Create a temporary span element to use as an anchor for scrolling\n // We can't use the anchor node directly because if it's a Text node, calling scrollIntoView() on it will throw an error\n const tempElement = document.createElement('span');\n // Collapse the range to its end point\n // This means the start and end points of the range will be the same, and it will not contain any content\n range.collapse(false);\n // Insert the temporary element at the cursor's position at the end of the range\n range.insertNode(tempElement);\n\n // Scroll the temporary element into view\n // the element will be aligned at the center of the scroll container, otherwise, text and images may be positioned incorrectly\n tempElement.scrollIntoView({\n block: 'center'\n });\n tempElement.remove();\n }\n};\n"]}
|
@@ -15,7 +15,7 @@ export declare enum UpdateEvent {
|
|
15
15
|
export declare class UpdateContentPlugin implements EditorPlugin {
|
16
16
|
private editor;
|
17
17
|
private disposer;
|
18
|
-
onUpdate: ((event: UpdateEvent) => void) | null;
|
18
|
+
onUpdate: ((event: UpdateEvent, imageSrcArray?: Array<string>) => void) | null;
|
19
19
|
getName(): string;
|
20
20
|
/**
|
21
21
|
* Initialize this plugin
|
package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/UpdateContentPlugin.js
CHANGED
@@ -12,6 +12,11 @@ export var UpdateEvent;
|
|
12
12
|
UpdateEvent["UserInput"] = "UserInput";
|
13
13
|
UpdateEvent["Blur"] = "Blur";
|
14
14
|
})(UpdateEvent || (UpdateEvent = {}));
|
15
|
+
var Keys;
|
16
|
+
(function (Keys) {
|
17
|
+
Keys[Keys["BACKSPACE"] = 8] = "BACKSPACE";
|
18
|
+
Keys[Keys["DELETE"] = 46] = "DELETE";
|
19
|
+
})(Keys || (Keys = {}));
|
15
20
|
/**
|
16
21
|
* A plugin to handle content update
|
17
22
|
*/
|
@@ -49,9 +54,11 @@ export class UpdateContentPlugin {
|
|
49
54
|
}
|
50
55
|
}
|
51
56
|
onPluginEvent(event) {
|
57
|
+
var _a;
|
52
58
|
if (this.onUpdate === null) {
|
53
59
|
return;
|
54
60
|
}
|
61
|
+
let imageSrcArray;
|
55
62
|
switch (event.eventType) {
|
56
63
|
case PluginEventType.EditorReady:
|
57
64
|
this.onUpdate(UpdateEvent.Init);
|
@@ -60,7 +67,26 @@ export class UpdateContentPlugin {
|
|
60
67
|
this.onUpdate(UpdateEvent.Dispose);
|
61
68
|
break;
|
62
69
|
case PluginEventType.ContentChanged:
|
63
|
-
|
70
|
+
if (event.source.toLowerCase() === 'cut' ||
|
71
|
+
(event.source.toLowerCase() === 'keyboard' && (event.data === Keys.BACKSPACE || event.data === Keys.DELETE))) {
|
72
|
+
(_a = event.contentModel) === null || _a === void 0 ? void 0 : _a.blocks.map((block) => {
|
73
|
+
if (block.blockType === 'Paragraph') {
|
74
|
+
const segments = block.segments;
|
75
|
+
segments.map((segment) => {
|
76
|
+
if (segment.segmentType === 'Image') {
|
77
|
+
if (!imageSrcArray) {
|
78
|
+
imageSrcArray = [];
|
79
|
+
}
|
80
|
+
imageSrcArray === null || imageSrcArray === void 0 ? void 0 : imageSrcArray.push(segment.src);
|
81
|
+
}
|
82
|
+
});
|
83
|
+
}
|
84
|
+
});
|
85
|
+
}
|
86
|
+
else {
|
87
|
+
imageSrcArray = undefined;
|
88
|
+
}
|
89
|
+
this.onUpdate(UpdateEvent.ContentChanged, imageSrcArray);
|
64
90
|
break;
|
65
91
|
case PluginEventType.Input:
|
66
92
|
this.onUpdate(UpdateEvent.UserInput);
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"UpdateContentPlugin.js","sourceRoot":"","sources":["../../../../../../../../react-components/src/components/RichTextEditor/Plugins/UpdateContentPlugin.tsx"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAGlC,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAElE;;GAEG;AACH,MAAM,CAAN,IAAY,WAMX;AAND,WAAY,WAAW;IACrB,4BAAa,CAAA;IACb,kCAAmB,CAAA;IACnB,gDAAiC,CAAA;IACjC,sCAAuB,CAAA;IACvB,4BAAa,CAAA;AACf,CAAC,EANW,WAAW,KAAX,WAAW,QAMtB;AAED;;GAEG;AACH,MAAM,OAAO,mBAAmB;IAAhC;QACU,WAAM,GAAmB,IAAI,CAAC;QAC9B,aAAQ,GAAwB,IAAI,CAAC;QAC7C,4FAA4F;QAC5F,aAAQ,
|
1
|
+
{"version":3,"file":"UpdateContentPlugin.js","sourceRoot":"","sources":["../../../../../../../../react-components/src/components/RichTextEditor/Plugins/UpdateContentPlugin.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { EditorPlugin, IEditor, PluginEvent } from 'roosterjs-content-model-types';\nimport { PluginEventType } from '../../utils/RichTextEditorUtils';\n\n/**\n * An update mode to indicate when the content update happens\n */\nexport enum UpdateEvent {\n Init = 'Init',\n Dispose = 'Dispose',\n ContentChanged = 'ContentChanged',\n UserInput = 'UserInput',\n Blur = 'Blur'\n}\n\nconst enum Keys {\n BACKSPACE = 8,\n DELETE = 46\n}\n\n/**\n * A plugin to handle content update\n */\nexport class UpdateContentPlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n private disposer: (() => void) | null = null;\n // don't set callback in constructor to be able to update callback without plugin recreation\n onUpdate: ((event: UpdateEvent, imageSrcArray?: Array<string>) => void) | null = null;\n\n getName(): string {\n return 'UpdateContentPlugin';\n }\n\n /**\n * Initialize this plugin\n * @param editor The editor instance\n */\n initialize(editor: IEditor): void {\n this.editor = editor;\n this.disposer = this.editor.attachDomEvent({\n blur: { beforeDispatch: this.onBlur }\n });\n }\n\n dispose(): void {\n this.editor = null;\n\n if (this.disposer) {\n this.disposer();\n this.disposer = null;\n }\n }\n\n onPluginEvent(event: PluginEvent): void {\n if (this.onUpdate === null) {\n return;\n }\n let imageSrcArray: Array<string> | undefined;\n\n switch (event.eventType) {\n case PluginEventType.EditorReady:\n this.onUpdate(UpdateEvent.Init);\n break;\n\n case PluginEventType.BeforeDispose:\n this.onUpdate(UpdateEvent.Dispose);\n break;\n\n case PluginEventType.ContentChanged:\n if (\n event.source.toLowerCase() === 'cut' ||\n (event.source.toLowerCase() === 'keyboard' && (event.data === Keys.BACKSPACE || event.data === Keys.DELETE))\n ) {\n event.contentModel?.blocks.map((block) => {\n if (block.blockType === 'Paragraph') {\n const segments = block.segments;\n segments.map((segment) => {\n if (segment.segmentType === 'Image') {\n if (!imageSrcArray) {\n imageSrcArray = [];\n }\n imageSrcArray?.push(segment.src);\n }\n });\n }\n });\n } else {\n imageSrcArray = undefined;\n }\n this.onUpdate(UpdateEvent.ContentChanged, imageSrcArray);\n break;\n\n case PluginEventType.Input:\n this.onUpdate(UpdateEvent.UserInput);\n break;\n }\n }\n\n private onBlur = (): void => {\n if (this.onUpdate === null) {\n return;\n }\n this.onUpdate(UpdateEvent.Blur);\n };\n}\n"]}
|
@@ -17,7 +17,7 @@ export interface RichTextEditorStyleProps {
|
|
17
17
|
*/
|
18
18
|
export interface RichTextEditorProps {
|
19
19
|
initialContent?: string;
|
20
|
-
onChange: (newValue?: string) => void;
|
20
|
+
onChange: (newValue?: string, imageSrcArray?: Array<string>) => void;
|
21
21
|
onKeyDown?: (ev: KeyboardEvent) => void;
|
22
22
|
onContentModelUpdate?: (contentModel: ContentModelDocument | undefined) => void;
|
23
23
|
contentModel?: ContentModelDocument | undefined;
|
@@ -29,6 +29,7 @@ export interface RichTextEditorProps {
|
|
29
29
|
onPaste?: (event: {
|
30
30
|
content: DocumentFragment;
|
31
31
|
}) => void;
|
32
|
+
onUploadInlineImage?: (imageUrl: string, imageFileName: string) => void;
|
32
33
|
}
|
33
34
|
/**
|
34
35
|
* Represents a reference to the RichTextEditor component.
|
@@ -14,7 +14,7 @@ import { RichTextToolbar } from './Toolbar/RichTextToolbar';
|
|
14
14
|
import { RichTextToolbarPlugin } from './Plugins/RichTextToolbarPlugin';
|
15
15
|
import { ContextMenuPlugin } from './Plugins/ContextMenuPlugin';
|
16
16
|
import { TableEditContextMenuProvider } from './Plugins/TableEditContextMenuProvider';
|
17
|
-
import { borderApplier, dataSetApplier } from '../utils/RichTextEditorUtils';
|
17
|
+
import { borderApplier, dataSetApplier, DefaultSanitizers } from '../utils/RichTextEditorUtils';
|
18
18
|
import { ContextualMenu } from '@fluentui/react';
|
19
19
|
import { PlaceholderPlugin } from './Plugins/PlaceholderPlugin';
|
20
20
|
/**
|
@@ -25,7 +25,9 @@ import { PlaceholderPlugin } from './Plugins/PlaceholderPlugin';
|
|
25
25
|
export const RichTextEditor = React.forwardRef((props, ref) => {
|
26
26
|
const { initialContent, onChange, placeholderText, strings, showRichTextEditorFormatting, autoFocus, onKeyDown, onContentModelUpdate, contentModel,
|
27
27
|
/* @conditional-compile-remove(rich-text-editor-image-upload) */
|
28
|
-
onPaste
|
28
|
+
onPaste,
|
29
|
+
/* @conditional-compile-remove(rich-text-editor-image-upload) */
|
30
|
+
onUploadInlineImage } = props;
|
29
31
|
const editor = useRef(null);
|
30
32
|
const editorDiv = useRef(null);
|
31
33
|
const theme = useTheme();
|
@@ -39,15 +41,18 @@ export const RichTextEditor = React.forwardRef((props, ref) => {
|
|
39
41
|
},
|
40
42
|
setEmptyContent() {
|
41
43
|
if (editor.current) {
|
42
|
-
editor.current.formatContentModel;
|
43
44
|
// remove all content from the editor and update the model
|
44
45
|
// ContentChanged event will be sent by RoosterJS automatically
|
45
46
|
editor.current.formatContentModel((model) => {
|
46
|
-
|
47
|
+
// Create a new empty paragraph with selection marker
|
48
|
+
// this is needed for correct processing of images after the content is deleted
|
49
|
+
const block = createParagraph(true);
|
50
|
+
setSelectionAfterLastSegment(model, block);
|
51
|
+
model.blocks = [block];
|
47
52
|
return true;
|
48
53
|
});
|
49
54
|
//reset content model
|
50
|
-
onContentModelUpdate && onContentModelUpdate(
|
55
|
+
onContentModelUpdate && onContentModelUpdate(editor.current.getContentModelCopy('disconnected'));
|
51
56
|
}
|
52
57
|
},
|
53
58
|
getPlainContent() {
|
@@ -90,9 +95,12 @@ export const RichTextEditor = React.forwardRef((props, ref) => {
|
|
90
95
|
const updatePlugin = useMemo(() => {
|
91
96
|
return new UpdateContentPlugin();
|
92
97
|
}, []);
|
98
|
+
const copyPastePlugin = useMemo(() => {
|
99
|
+
return new CopyPastePlugin();
|
100
|
+
}, []);
|
93
101
|
useEffect(() => {
|
94
102
|
// don't set callback in plugin constructor to update callback without plugin recreation
|
95
|
-
updatePlugin.onUpdate = (event) => {
|
103
|
+
updatePlugin.onUpdate = (event, imageSrcArray) => {
|
96
104
|
if (editor.current === null) {
|
97
105
|
return;
|
98
106
|
}
|
@@ -100,10 +108,14 @@ export const RichTextEditor = React.forwardRef((props, ref) => {
|
|
100
108
|
onContentModelUpdate && onContentModelUpdate(editor.current.getContentModelCopy('disconnected'));
|
101
109
|
}
|
102
110
|
else {
|
103
|
-
onChange && onChange(exportContent(editor.current));
|
111
|
+
onChange && onChange(exportContent(editor.current), imageSrcArray);
|
104
112
|
}
|
105
113
|
};
|
106
114
|
}, [onChange, onContentModelUpdate, updatePlugin]);
|
115
|
+
/* @conditional-compile-remove(rich-text-editor-image-upload) */
|
116
|
+
useEffect(() => {
|
117
|
+
copyPastePlugin.onUploadInlineImage = onUploadInlineImage;
|
118
|
+
}, [copyPastePlugin, onUploadInlineImage]);
|
107
119
|
const keyboardInputPlugin = useMemo(() => {
|
108
120
|
return new KeyboardInputPlugin();
|
109
121
|
}, []);
|
@@ -127,9 +139,6 @@ export const RichTextEditor = React.forwardRef((props, ref) => {
|
|
127
139
|
const onContextMenuDismiss = useCallback(() => {
|
128
140
|
setContextMenuProps(null);
|
129
141
|
}, []);
|
130
|
-
const copyPastePlugin = useMemo(() => {
|
131
|
-
return new CopyPastePlugin();
|
132
|
-
}, []);
|
133
142
|
/* @conditional-compile-remove(rich-text-editor-image-upload) */
|
134
143
|
useEffect(() => {
|
135
144
|
copyPastePlugin.onPaste = onPaste;
|
@@ -138,7 +147,12 @@ export const RichTextEditor = React.forwardRef((props, ref) => {
|
|
138
147
|
const contentEdit = new EditPlugin({ handleTabKey: false });
|
139
148
|
// AutoFormatPlugin previously was a part of the edit plugin
|
140
149
|
const autoFormatPlugin = new AutoFormatPlugin({ autoBullet: true, autoNumbering: true, autoLink: true });
|
141
|
-
const roosterPastePlugin = new PastePlugin(false
|
150
|
+
const roosterPastePlugin = new PastePlugin(false, {
|
151
|
+
additionalDisallowedTags: ['head', '!doctype', '!cdata', '#comment'],
|
152
|
+
additionalAllowedTags: [],
|
153
|
+
styleSanitizers: DefaultSanitizers,
|
154
|
+
attributeSanitizers: {}
|
155
|
+
});
|
142
156
|
const shortcutPlugin = new ShortcutPlugin();
|
143
157
|
const contextMenuPlugin = new ContextMenuPlugin(onContextMenuRender, onContextMenuDismiss);
|
144
158
|
return [
|
@@ -224,11 +238,14 @@ const createEditorInitialModel = (initialContent, contentModel) => {
|
|
224
238
|
lastBlock = createParagraph(true);
|
225
239
|
initialModel.blocks.push(lastBlock);
|
226
240
|
}
|
227
|
-
|
228
|
-
lastBlock.segments.push(marker);
|
229
|
-
setSelection(initialModel, marker);
|
241
|
+
setSelectionAfterLastSegment(initialModel, lastBlock);
|
230
242
|
}
|
231
243
|
return initialModel;
|
232
244
|
}
|
233
245
|
};
|
246
|
+
const setSelectionAfterLastSegment = (model, block) => {
|
247
|
+
const marker = createSelectionMarker();
|
248
|
+
block.segments.push(marker);
|
249
|
+
setSelection(model, marker);
|
250
|
+
};
|
234
251
|
//# sourceMappingURL=RichTextEditor.js.map
|