Skip to content

Commit b658baf

Browse files
carocao-msftdmceachernmsftgithub-actions[bot]PorterNancommunication-ui-bot
authored
Display correct guidance text for device permission error on safari (#2590)
* correct guidance text safari * Change files * Duplicate change files for beta release * correct guidance text safari * correct guidance text safari * [CallReadiness] browser version tests for allowingUnsupportedBrowser (#2585) * Add continue button to browserVersion UI * update styles * add new button logic to call adapter * add logic to callWithChat * fix handler logic * fix styles * Fix cc and build stable API * remove console * Change files * Duplicate change files for beta release * update strings * update styles for strings * update per comments * update UI state naming * build API * fix test errors * Update packages/react-composites CallComposite browser test snapshots * Update packages/react-composites CallComposite browser test snapshots * update styles * Update packages/react-composites CallComposite browser test snapshots * update styles * Update packages/react-composites CallComposite browser test snapshots * Add new tests * Change files * Duplicate change files for beta release * Update packages/react-composites CallComposite browser test snapshots * fix styles and storybook bug * Update packages/react-composites CallComposite browser test snapshots Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Fix CTE beta feature with stable sdk compatibility issue (#2572) * Fix unreachable bug when use stable sdk with beta Co-authored-by: Nan Jiang <jinan@microsoft.com> * Validate identifier before creating the adapter (#2313) * Add a step to validate identifier Co-authored-by: Nan Jiang <jinan@microsoft.com> * [CallReadiness] Update composite useAdapted selector to get new StatefulCallClientState (#2593) * update adapted selector function * Change files * Duplicate change files for beta release * remove console * use environment info * build files * build files * pr change * pr change * pr change * pr change Co-authored-by: Donald McEachern <94866715+dmceachernmsft@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Porter Nan <jiangnanhello@live.com> Co-authored-by: Nan Jiang <jinan@microsoft.com>
1 parent 2e995fc commit b658baf

17 files changed

Lines changed: 178 additions & 15 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "patch",
3+
"comment": "Display correct error text and guidance text for device permission errors on safari browser",
4+
"packageName": "@azure/communication-react",
5+
"email": "carolinecao@microsoft.com",
6+
"dependentChangeType": "patch"
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "patch",
3+
"comment": "Display correct error text and guidance text for device permission errors on safari browser",
4+
"packageName": "@azure/communication-react",
5+
"email": "carolinecao@microsoft.com",
6+
"dependentChangeType": "patch"
7+
}

packages/calling-component-bindings/src/baseSelectors.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,13 @@ export const getDiagnostics = (
122122
export const getCallState = (state: CallClientState, props: CallingBaseSelectorProps): string =>
123123
state.calls[props.callId]?.state;
124124

125-
/* @conditional-compile-remove(unsupported-browser) */
126125
/**
127126
* @private
128127
*/
129-
export const getEnvironmentInfo = (state: CallClientState): EnvironmentInfo | undefined => {
128+
export const getEnvironmentInfo = (
129+
state: CallClientState
130+
): undefined | /* @conditional-compile-remove(unsupported-browser) */ EnvironmentInfo => {
131+
/* @conditional-compile-remove(unsupported-browser) */
130132
return state.environmentInfo;
133+
return undefined;
131134
};

packages/calling-component-bindings/src/errorBarSelector.ts

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT license.
33

4-
import { CallingBaseSelectorProps, getDeviceManager, getDiagnostics, getLatestErrors } from './baseSelectors';
4+
import {
5+
CallingBaseSelectorProps,
6+
getDeviceManager,
7+
getDiagnostics,
8+
getLatestErrors,
9+
getEnvironmentInfo
10+
} from './baseSelectors';
511
import { ActiveErrorMessage, ErrorType } from '@internal/react-components';
612
import { createSelector } from 'reselect';
713
import { CallClientState, CallErrors, CallErrorTarget } from '@internal/calling-stateful-client';
814
import { DiagnosticQuality } from '@azure/communication-calling';
9-
1015
/**
1116
* Selector type for {@link ErrorBar} component.
1217
*
@@ -32,8 +37,13 @@ export type ErrorBarSelector = (
3237
* @public
3338
*/
3439
export const errorBarSelector: ErrorBarSelector = createSelector(
35-
[getLatestErrors, getDiagnostics, getDeviceManager],
36-
(latestErrors: CallErrors, diagnostics, deviceManager): { activeErrorMessages: ActiveErrorMessage[] } => {
40+
[getLatestErrors, getDiagnostics, getDeviceManager, getEnvironmentInfo],
41+
(
42+
latestErrors: CallErrors,
43+
diagnostics,
44+
deviceManager,
45+
environmentInfo
46+
): { activeErrorMessages: ActiveErrorMessage[] } => {
3747
// The order in which the errors are returned is significant: The `ErrorBar` shows errors on the UI in that order.
3848
// There are several options for the ordering:
3949
// - Sorted by when the errors happened (latest first / oldest first).
@@ -43,6 +53,12 @@ export const errorBarSelector: ErrorBarSelector = createSelector(
4353
// have timestamps for errors.
4454
const activeErrorMessages: ActiveErrorMessage[] = [];
4555

56+
const isSafari = (): boolean => {
57+
/* @conditional-compile-remove(unsupported-browser) */
58+
return environmentInfo?.environment.browser === 'safari';
59+
return /^((?!chrome|android|crios|fxios).)*safari/i.test(navigator.userAgent);
60+
};
61+
4662
// Errors reported via diagnostics are more reliable than from API method failures, so process those first.
4763
if (
4864
diagnostics?.network.latest.networkReceiveQuality?.value === DiagnosticQuality.Bad ||
@@ -56,7 +72,10 @@ export const errorBarSelector: ErrorBarSelector = createSelector(
5672
if (diagnostics?.media.latest.noMicrophoneDevicesEnumerated?.value === true) {
5773
activeErrorMessages.push({ type: 'callNoMicrophoneFound' });
5874
}
59-
if (deviceManager.deviceAccess?.audio === false) {
75+
if (deviceManager.deviceAccess?.audio === false && isSafari()) {
76+
activeErrorMessages.push({ type: 'callMicrophoneAccessDeniedSafari' });
77+
}
78+
if (deviceManager.deviceAccess?.audio === false && !isSafari()) {
6079
activeErrorMessages.push({ type: 'callMicrophoneAccessDenied' });
6180
}
6281
if (diagnostics?.media.latest.microphonePermissionDenied?.value === true) {
@@ -85,8 +104,9 @@ export const errorBarSelector: ErrorBarSelector = createSelector(
85104
activeErrorMessages.push({ type: 'callVideoRecoveredBySystem' });
86105
}
87106
}
88-
89-
if (deviceManager.deviceAccess?.video === false) {
107+
if (deviceManager.deviceAccess?.video === false && isSafari()) {
108+
activeErrorMessages.push({ type: 'callCameraAccessDeniedSafari' });
109+
} else if (deviceManager.deviceAccess?.video === false) {
90110
activeErrorMessages.push({ type: 'callCameraAccessDenied' });
91111
} else {
92112
if (diagnostics?.media.latest.cameraFreeze?.value === true) {

packages/communication-react/review/beta/communication-react.api.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1419,6 +1419,7 @@ export interface CommonCallingHandlers {
14191419
// @beta
14201420
export interface CommonDomainPermissionsProps {
14211421
appName: string;
1422+
isSafari?: boolean;
14221423
onContinueAnywayClick?: () => void;
14231424
onTroubleshootingClick?: () => void;
14241425
styles?: DomainPermissionsStyles;
@@ -1497,10 +1498,12 @@ export interface ComponentStrings {
14971498
BrowserPermissionDeniedIOS: BrowserPermissionDeniedIOSStrings;
14981499
CameraAndMicrophoneDomainPermissionsCheck: DomainPermissionsStrings;
14991500
CameraAndMicrophoneDomainPermissionsDenied: DomainPermissionsStrings;
1501+
CameraAndMicrophoneDomainPermissionsDeniedSafari: DomainPermissionsStrings;
15001502
CameraAndMicrophoneDomainPermissionsRequest: DomainPermissionsStrings;
15011503
cameraButton: CameraButtonStrings;
15021504
CameraDomainPermissionsCheck: DomainPermissionsStrings;
15031505
CameraDomainPermissionsDenied: DomainPermissionsStrings;
1506+
CameraDomainPermissionsDeniedSafari: DomainPermissionsStrings;
15041507
CameraDomainPermissionsRequest: DomainPermissionsStrings;
15051508
devicesButton: DevicesButtonStrings;
15061509
dialpad: DialpadStrings;
@@ -1512,6 +1515,7 @@ export interface ComponentStrings {
15121515
microphoneButton: MicrophoneButtonStrings;
15131516
MicrophoneDomainPermissionsCheck: DomainPermissionsStrings;
15141517
MicrophoneDomainPermissionsDenied: DomainPermissionsStrings;
1518+
MicrophoneDomainPermissionsDeniedSafari: DomainPermissionsStrings;
15151519
MicrophoneDomainPermissionsRequest: DomainPermissionsStrings;
15161520
participantItem: ParticipantItemStrings;
15171521
participantsButton: ParticipantsButtonStrings;
@@ -2123,12 +2127,14 @@ export interface ErrorBarProps extends IMessageBarProps {
21232127
export interface ErrorBarStrings {
21242128
accessDenied: string;
21252129
callCameraAccessDenied: string;
2130+
callCameraAccessDeniedSafari: string;
21262131
callCameraAlreadyInUse: string;
21272132
callLocalVideoFreeze: string;
21282133
callMacOsCameraAccessDenied: string;
21292134
callMacOsMicrophoneAccessDenied: string;
21302135
callMacOsScreenShareAccessDenied: string;
21312136
callMicrophoneAccessDenied: string;
2137+
callMicrophoneAccessDeniedSafari: string;
21322138
callMicrophoneMutedBySystem: string;
21332139
callMicrophoneUnmutedBySystem: string;
21342140
callNetworkQualityLow: string;

packages/communication-react/review/stable/communication-react.api.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1624,12 +1624,14 @@ export interface ErrorBarProps extends IMessageBarProps {
16241624
export interface ErrorBarStrings {
16251625
accessDenied: string;
16261626
callCameraAccessDenied: string;
1627+
callCameraAccessDeniedSafari: string;
16271628
callCameraAlreadyInUse: string;
16281629
callLocalVideoFreeze: string;
16291630
callMacOsCameraAccessDenied: string;
16301631
callMacOsMicrophoneAccessDenied: string;
16311632
callMacOsScreenShareAccessDenied: string;
16321633
callMicrophoneAccessDenied: string;
1634+
callMicrophoneAccessDeniedSafari: string;
16331635
callMicrophoneMutedBySystem: string;
16341636
callMicrophoneUnmutedBySystem: string;
16351637
callNetworkQualityLow: string;

packages/react-components/review/beta/react-components.api.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ export interface ChatMessage extends MessageCommon {
237237
// @beta
238238
export interface CommonDomainPermissionsProps {
239239
appName: string;
240+
isSafari?: boolean;
240241
onContinueAnywayClick?: () => void;
241242
onTroubleshootingClick?: () => void;
242243
styles?: DomainPermissionsStyles;
@@ -351,10 +352,12 @@ export interface ComponentStrings {
351352
BrowserPermissionDeniedIOS: BrowserPermissionDeniedIOSStrings;
352353
CameraAndMicrophoneDomainPermissionsCheck: DomainPermissionsStrings;
353354
CameraAndMicrophoneDomainPermissionsDenied: DomainPermissionsStrings;
355+
CameraAndMicrophoneDomainPermissionsDeniedSafari: DomainPermissionsStrings;
354356
CameraAndMicrophoneDomainPermissionsRequest: DomainPermissionsStrings;
355357
cameraButton: CameraButtonStrings;
356358
CameraDomainPermissionsCheck: DomainPermissionsStrings;
357359
CameraDomainPermissionsDenied: DomainPermissionsStrings;
360+
CameraDomainPermissionsDeniedSafari: DomainPermissionsStrings;
358361
CameraDomainPermissionsRequest: DomainPermissionsStrings;
359362
devicesButton: DevicesButtonStrings;
360363
dialpad: DialpadStrings;
@@ -366,6 +369,7 @@ export interface ComponentStrings {
366369
microphoneButton: MicrophoneButtonStrings;
367370
MicrophoneDomainPermissionsCheck: DomainPermissionsStrings;
368371
MicrophoneDomainPermissionsDenied: DomainPermissionsStrings;
372+
MicrophoneDomainPermissionsDeniedSafari: DomainPermissionsStrings;
369373
MicrophoneDomainPermissionsRequest: DomainPermissionsStrings;
370374
participantItem: ParticipantItemStrings;
371375
participantsButton: ParticipantsButtonStrings;
@@ -733,12 +737,14 @@ export interface ErrorBarProps extends IMessageBarProps {
733737
export interface ErrorBarStrings {
734738
accessDenied: string;
735739
callCameraAccessDenied: string;
740+
callCameraAccessDeniedSafari: string;
736741
callCameraAlreadyInUse: string;
737742
callLocalVideoFreeze: string;
738743
callMacOsCameraAccessDenied: string;
739744
callMacOsMicrophoneAccessDenied: string;
740745
callMacOsScreenShareAccessDenied: string;
741746
callMicrophoneAccessDenied: string;
747+
callMicrophoneAccessDeniedSafari: string;
742748
callMicrophoneMutedBySystem: string;
743749
callMicrophoneUnmutedBySystem: string;
744750
callNetworkQualityLow: string;

packages/react-components/review/stable/react-components.api.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,12 +576,14 @@ export interface ErrorBarProps extends IMessageBarProps {
576576
export interface ErrorBarStrings {
577577
accessDenied: string;
578578
callCameraAccessDenied: string;
579+
callCameraAccessDeniedSafari: string;
579580
callCameraAlreadyInUse: string;
580581
callLocalVideoFreeze: string;
581582
callMacOsCameraAccessDenied: string;
582583
callMacOsMicrophoneAccessDenied: string;
583584
callMacOsScreenShareAccessDenied: string;
584585
callMicrophoneAccessDenied: string;
586+
callMicrophoneAccessDeniedSafari: string;
585587
callMicrophoneMutedBySystem: string;
586588
callMicrophoneUnmutedBySystem: string;
587589
callNetworkQualityLow: string;

packages/react-components/src/components/DevicePermissions/DomainPermissions.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ export interface CommonDomainPermissionsProps {
2323
* Type of the Domain Permissions component.
2424
*/
2525
type: 'request' | 'denied' | 'check';
26+
/**
27+
* Whether we are using safari browser or not
28+
*/
29+
isSafari?: boolean;
2630
/**
2731
* Action to be taken by the more help link. Possible to send to external page or show other modal.
2832
* If this is not provided the button will not be shown.
@@ -73,7 +77,9 @@ export const CameraAndMicrophoneDomainPermissions = (props: CameraAndMicrophoneD
7377
/* @conditional-compile-remove(call-readiness) */
7478
const strings = useShallowMerge(
7579
props.type === 'denied'
76-
? locale.CameraAndMicrophoneDomainPermissionsDenied
80+
? props.isSafari
81+
? locale.CameraAndMicrophoneDomainPermissionsDeniedSafari
82+
: locale.CameraAndMicrophoneDomainPermissionsDenied
7783
: props.type === 'request'
7884
? locale.CameraAndMicrophoneDomainPermissionsRequest
7985
: locale.CameraAndMicrophoneDomainPermissionsCheck,
@@ -133,7 +139,9 @@ export const MicrophoneDomainPermissions = (props: MicrophoneDomainPermissionsPr
133139
/* @conditional-compile-remove(call-readiness) */
134140
const strings = useShallowMerge(
135141
props.type === 'denied'
136-
? locale.MicrophoneDomainPermissionsDenied
142+
? props.isSafari
143+
? locale.MicrophoneDomainPermissionsDeniedSafari
144+
: locale.MicrophoneDomainPermissionsDenied
137145
: props.type === 'request'
138146
? locale.MicrophoneDomainPermissionsRequest
139147
: locale.MicrophoneDomainPermissionsCheck,
@@ -186,7 +194,9 @@ export const CameraDomainPermissions = (props: CameraDomainPermissionsProps): JS
186194
/* @conditional-compile-remove(call-readiness) */
187195
const strings = useShallowMerge(
188196
props.type === 'denied'
189-
? locale.CameraDomainPermissionsDenied
197+
? props.isSafari
198+
? locale.CameraDomainPermissionsDeniedSafari
199+
: locale.CameraDomainPermissionsDenied
190200
: props.type === 'request'
191201
? locale.CameraDomainPermissionsRequest
192202
: locale.CameraDomainPermissionsCheck,

packages/react-components/src/components/ErrorBar.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,11 @@ export interface ErrorBarStrings {
133133
*/
134134
callMicrophoneAccessDenied: string;
135135

136+
/**
137+
* Message shown when microphone can be enumerated but access is blocked by the system, for safari browsers
138+
*/
139+
callMicrophoneAccessDeniedSafari: string;
140+
136141
/**
137142
* Message shown when microphone is muted by the system (not by local or remote participants)
138143
*/
@@ -160,6 +165,11 @@ export interface ErrorBarStrings {
160165
*/
161166
callCameraAccessDenied: string;
162167

168+
/**
169+
* Message shown when camera can be enumerated but access is blocked by the system, for safari browsers
170+
*/
171+
callCameraAccessDeniedSafari: string;
172+
163173
/**
164174
* Message shown when local video fails to start because camera is already in use by
165175
* another applciation.

0 commit comments

Comments
 (0)