diff --git a/change-beta/@azure-communication-react-breakout-room-prompt-b2c3d4e5.json b/change-beta/@azure-communication-react-breakout-room-prompt-b2c3d4e5.json new file mode 100644 index 00000000000..d483dfad989 --- /dev/null +++ b/change-beta/@azure-communication-react-breakout-room-prompt-b2c3d4e5.json @@ -0,0 +1,9 @@ +{ + "type": "patch", + "area": "fix", + "workstream": "Breakout rooms", + "comment": "Add prompt notification for assigned breakout room changes when auto move is false", + "packageName": "@azure/communication-react", + "email": "miguelgamis@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/change/@azure-communication-react-breakout-room-prompt-b2c3d4e5.json b/change/@azure-communication-react-breakout-room-prompt-b2c3d4e5.json new file mode 100644 index 00000000000..d483dfad989 --- /dev/null +++ b/change/@azure-communication-react-breakout-room-prompt-b2c3d4e5.json @@ -0,0 +1,9 @@ +{ + "type": "patch", + "area": "fix", + "workstream": "Breakout rooms", + "comment": "Add prompt notification for assigned breakout room changes when auto move is false", + "packageName": "@azure/communication-react", + "email": "miguelgamis@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/calling-component-bindings/src/notificationStackSelector.ts b/packages/calling-component-bindings/src/notificationStackSelector.ts index 45ed1fa20d4..23382eee55c 100644 --- a/packages/calling-component-bindings/src/notificationStackSelector.ts +++ b/packages/calling-component-bindings/src/notificationStackSelector.ts @@ -256,6 +256,13 @@ export const notificationStackSelector: NotificationStackSelector = createSelect timestamp: latestNotifications['assignedBreakoutRoomChanged'].timestamp }); } + if (latestNotifications['assignedBreakoutRoomChangedPromptJoin'] && assignedBreakoutRoom) { + activeNotifications.push({ + type: 'assignedBreakoutRoomChangedPromptJoin', + timestamp: latestNotifications['assignedBreakoutRoomChangedPromptJoin'].timestamp, + onClickPrimaryButton: () => assignedBreakoutRoom.join() + }); + } if (latestNotifications['assignedBreakoutRoomClosed']) { activeNotifications.push({ type: 'assignedBreakoutRoomClosed', diff --git a/packages/calling-stateful-client/src/BreakoutRoomsSubscriber.ts b/packages/calling-stateful-client/src/BreakoutRoomsSubscriber.ts index 7b9cdfaf903..63d81040848 100644 --- a/packages/calling-stateful-client/src/BreakoutRoomsSubscriber.ts +++ b/packages/calling-stateful-client/src/BreakoutRoomsSubscriber.ts @@ -83,8 +83,12 @@ export class BreakoutRoomsSubscriber { callState.breakoutRooms?.breakoutRoomDisplayName && callState.breakoutRooms.breakoutRoomDisplayName !== breakoutRoom.displayName ) { + const target: NotificationTarget = + breakoutRoom.autoMoveParticipantToBreakoutRoom === false + ? 'assignedBreakoutRoomChangedPromptJoin' + : 'assignedBreakoutRoomChanged'; this._context.setLatestNotification(this._callIdRef.callId, { - target: 'assignedBreakoutRoomChanged', + target, timestamp: new Date(Date.now()) }); } else if ( @@ -102,12 +106,14 @@ export class BreakoutRoomsSubscriber { this._context.deleteLatestNotification('assignedBreakoutRoomOpened', this._callIdRef.callId); this._context.deleteLatestNotification('assignedBreakoutRoomOpenedPromptJoin', this._callIdRef.callId); this._context.deleteLatestNotification('assignedBreakoutRoomChanged', this._callIdRef.callId); + this._context.deleteLatestNotification('assignedBreakoutRoomChangedPromptJoin', this._callIdRef.callId); this._context.deleteLatestNotification('breakoutRoomJoined', this._callIdRef.callId); } else if (breakoutRoom.state === 'closed') { // This scenario covers the case where the breakout room is closed this._context.deleteLatestNotification('assignedBreakoutRoomOpened', this._callIdRef.callId); this._context.deleteLatestNotification('assignedBreakoutRoomOpenedPromptJoin', this._callIdRef.callId); this._context.deleteLatestNotification('assignedBreakoutRoomChanged', this._callIdRef.callId); + this._context.deleteLatestNotification('assignedBreakoutRoomChangedPromptJoin', this._callIdRef.callId); this._context.deleteLatestNotification('breakoutRoomJoined', this._callIdRef.callId); this._context.deleteLatestNotification('breakoutRoomClosingSoon', this._callIdRef.callId); clearTimeout(this._breakoutRoomClosingSoonTimeoutId); @@ -129,6 +135,7 @@ export class BreakoutRoomsSubscriber { this._context.deleteLatestNotification('assignedBreakoutRoomOpened', this._callIdRef.callId); this._context.deleteLatestNotification('assignedBreakoutRoomOpenedPromptJoin', this._callIdRef.callId); this._context.deleteLatestNotification('assignedBreakoutRoomChanged', this._callIdRef.callId); + this._context.deleteLatestNotification('assignedBreakoutRoomChangedPromptJoin', this._callIdRef.callId); // Send latest notification for breakoutRoomJoined on behalf of the call that was joined. this._context.setLatestNotification(call.id, { diff --git a/packages/calling-stateful-client/src/CallClientState.ts b/packages/calling-stateful-client/src/CallClientState.ts index f4318142340..6ee626f3573 100644 --- a/packages/calling-stateful-client/src/CallClientState.ts +++ b/packages/calling-stateful-client/src/CallClientState.ts @@ -1232,6 +1232,7 @@ export type NotificationTarget = | 'assignedBreakoutRoomOpened' | 'assignedBreakoutRoomOpenedPromptJoin' | 'assignedBreakoutRoomChanged' + | 'assignedBreakoutRoomChangedPromptJoin' | 'assignedBreakoutRoomClosed' | 'breakoutRoomJoined' | 'breakoutRoomClosingSoon' diff --git a/packages/communication-react/review/beta/communication-react.api.md b/packages/communication-react/review/beta/communication-react.api.md index 4b0ef516cf7..edbdc69c91a 100644 --- a/packages/communication-react/review/beta/communication-react.api.md +++ b/packages/communication-react/review/beta/communication-react.api.md @@ -4231,6 +4231,7 @@ export type NotificationStackSelector = (state: CallClientState, props: CallingB // @public export interface NotificationStackStrings { assignedBreakoutRoomChanged?: NotificationStrings; + assignedBreakoutRoomChangedPromptJoin?: NotificationStrings; assignedBreakoutRoomClosed?: NotificationStrings; assignedBreakoutRoomOpened?: NotificationStrings; assignedBreakoutRoomOpenedPromptJoin?: NotificationStrings; @@ -4307,7 +4308,7 @@ export interface NotificationStyles { } // @public (undocumented) -export type NotificationTarget = 'assignedBreakoutRoomOpened' | 'assignedBreakoutRoomOpenedPromptJoin' | 'assignedBreakoutRoomChanged' | 'assignedBreakoutRoomClosed' | 'breakoutRoomJoined' | 'breakoutRoomClosingSoon' | 'capabilityTurnVideoOnPresent' | 'capabilityTurnVideoOnAbsent' | 'capabilityUnmuteMicPresent' | 'capabilityUnmuteMicAbsent' | 'togetherModeStarted' | 'togetherModeEnded'; +export type NotificationTarget = 'assignedBreakoutRoomOpened' | 'assignedBreakoutRoomOpenedPromptJoin' | 'assignedBreakoutRoomChanged' | 'assignedBreakoutRoomChangedPromptJoin' | 'assignedBreakoutRoomClosed' | 'breakoutRoomJoined' | 'breakoutRoomClosingSoon' | 'capabilityTurnVideoOnPresent' | 'capabilityTurnVideoOnAbsent' | 'capabilityUnmuteMicPresent' | 'capabilityUnmuteMicAbsent' | 'togetherModeStarted' | 'togetherModeEnded'; // @public export type NotificationType = keyof NotificationStackStrings; diff --git a/packages/communication-react/review/stable/communication-react.api.md b/packages/communication-react/review/stable/communication-react.api.md index 5959da18001..4d93d2ded94 100644 --- a/packages/communication-react/review/stable/communication-react.api.md +++ b/packages/communication-react/review/stable/communication-react.api.md @@ -3836,6 +3836,7 @@ export type NotificationStackSelector = (state: CallClientState, props: CallingB // @public export interface NotificationStackStrings { assignedBreakoutRoomChanged?: NotificationStrings; + assignedBreakoutRoomChangedPromptJoin?: NotificationStrings; assignedBreakoutRoomClosed?: NotificationStrings; assignedBreakoutRoomOpened?: NotificationStrings; assignedBreakoutRoomOpenedPromptJoin?: NotificationStrings; @@ -3912,7 +3913,7 @@ export interface NotificationStyles { } // @public (undocumented) -export type NotificationTarget = 'assignedBreakoutRoomOpened' | 'assignedBreakoutRoomOpenedPromptJoin' | 'assignedBreakoutRoomChanged' | 'assignedBreakoutRoomClosed' | 'breakoutRoomJoined' | 'breakoutRoomClosingSoon' | 'capabilityTurnVideoOnPresent' | 'capabilityTurnVideoOnAbsent' | 'capabilityUnmuteMicPresent' | 'capabilityUnmuteMicAbsent' | 'togetherModeStarted' | 'togetherModeEnded'; +export type NotificationTarget = 'assignedBreakoutRoomOpened' | 'assignedBreakoutRoomOpenedPromptJoin' | 'assignedBreakoutRoomChanged' | 'assignedBreakoutRoomChangedPromptJoin' | 'assignedBreakoutRoomClosed' | 'breakoutRoomJoined' | 'breakoutRoomClosingSoon' | 'capabilityTurnVideoOnPresent' | 'capabilityTurnVideoOnAbsent' | 'capabilityUnmuteMicPresent' | 'capabilityUnmuteMicAbsent' | 'togetherModeStarted' | 'togetherModeEnded'; // @public export type NotificationType = keyof NotificationStackStrings; diff --git a/packages/react-components/src/components/NotificationStack.tsx b/packages/react-components/src/components/NotificationStack.tsx index 930beed5d3c..64de8ba8ad4 100644 --- a/packages/react-components/src/components/NotificationStack.tsx +++ b/packages/react-components/src/components/NotificationStack.tsx @@ -255,6 +255,10 @@ export interface NotificationStackStrings { * Message shown in notification when the user's assigned breakout room is changed */ assignedBreakoutRoomChanged?: NotificationStrings; + /** + * Message shown in notification when the user is prompted to join their new assigned breakout room + */ + assignedBreakoutRoomChangedPromptJoin?: NotificationStrings; /** * Message shown in notification when the user's assigned breakout room is closed */ diff --git a/packages/react-components/src/components/utils.ts b/packages/react-components/src/components/utils.ts index a1a63866fbc..314f0f77a88 100644 --- a/packages/react-components/src/components/utils.ts +++ b/packages/react-components/src/components/utils.ts @@ -353,6 +353,7 @@ export const customNotificationIconName: Partial<{ [key in NotificationType]: st assignedBreakoutRoomOpened: 'NotificationBarBreakoutRoomOpened', assignedBreakoutRoomOpenedPromptJoin: 'NotificationBarBreakoutRoomPromptJoin', assignedBreakoutRoomChanged: 'NotificationBarBreakoutRoomChanged', + assignedBreakoutRoomChangedPromptJoin: 'NotificationBarBreakoutRoomChanged', assignedBreakoutRoomClosed: 'NotificationBarBreakoutRoomClosed', breakoutRoomJoined: 'NotificationBarBreakoutRoomJoined', breakoutRoomClosingSoon: 'NotificationBarBreakoutRoomClosingSoon', diff --git a/packages/react-components/src/localization/locales/en-US/strings.json b/packages/react-components/src/localization/locales/en-US/strings.json index aaa391c5922..8decf4b003e 100644 --- a/packages/react-components/src/localization/locales/en-US/strings.json +++ b/packages/react-components/src/localization/locales/en-US/strings.json @@ -604,6 +604,12 @@ "message": "We'll move you to your assigned room in 5 seconds.", "dismissButtonAriaLabel": "Close" }, + "assignedBreakoutRoomChangedPromptJoin": { + "title": "Your breakout room has changed", + "message": "You've been assigned to a different breakout room.", + "dismissButtonAriaLabel": "Close", + "primaryButtonLabel": "Join room" + }, "assignedBreakoutRoomClosed": { "title": "Your breakout room has closed", "message": "We'll move you back to your meeting in 5 seconds.",