Skip to content

Commit 6a663c4

Browse files
[bugfix] Hide speaker dropdown for safari browser (#3964)
* Remove speaker dropdown for Safari browsers as speaker enumeration is not available for Safari browsers
1 parent ba51f11 commit 6a663c4

5 files changed

Lines changed: 72 additions & 19 deletions

File tree

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"type": "patch",
3+
"area": "fix",
4+
"workstream": "",
5+
"comment": "Remove speaker dropdown for Safari browsers as speaker enumeration is not available for Safari browsers",
6+
"packageName": "@azure/communication-react",
7+
"email": "edwardlee@microsoft.com",
8+
"dependentChangeType": "patch"
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"type": "patch",
3+
"area": "fix",
4+
"workstream": "",
5+
"comment": "Remove speaker dropdown for Safari browsers as speaker enumeration is not available for Safari browsers",
6+
"packageName": "@azure/communication-react",
7+
"email": "edwardlee@microsoft.com",
8+
"dependentChangeType": "patch"
9+
}

packages/react-composites/src/composites/CallComposite/components/LocalDeviceSettings.tsx

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ export const LocalDeviceSettings = (props: LocalDeviceSettingsType): JSX.Element
117117

118118
const cameraPermissionGranted = props.cameraPermissionGranted;
119119
const micPermissionGranted = props.microphonePermissionGranted;
120+
120121
let roleCanUseCamera = true;
121122
let roleCanUseMic = true;
122123

@@ -145,6 +146,9 @@ export const LocalDeviceSettings = (props: LocalDeviceSettingsType): JSX.Element
145146
const hasCameras = props.cameras.length > 0;
146147
const hasMicrophones = props.microphones.length > 0;
147148
const hasSpeakers = props.speakers.length > 0;
149+
/* @conditional-compile-remove(unsupported-browser) */
150+
const isSafariWithNoSpeakers =
151+
adapter.getState().environmentInfo?.environment.browser.toLowerCase() === 'safari' && !hasSpeakers;
148152

149153
const cameraGrantedDropdown = (
150154
<Dropdown
@@ -209,6 +213,33 @@ export const LocalDeviceSettings = (props: LocalDeviceSettingsType): JSX.Element
209213
</>
210214
);
211215

216+
const speakerDropdown = (
217+
<Dropdown
218+
aria-labelledby={'call-composite-local-sound-settings-label'}
219+
placeholder={hasSpeakers ? defaultPlaceHolder : noSpeakersLabel}
220+
styles={dropDownStyles(theme)}
221+
disabled={props.speakers.length === 0}
222+
options={getDropDownList(props.speakers)}
223+
defaultSelectedKey={props.selectedSpeaker ? props.selectedSpeaker.id : defaultDeviceId(props.speakers)}
224+
onChange={(
225+
event: React.FormEvent<HTMLDivElement>,
226+
option?: IDropdownOption | undefined,
227+
index?: number | undefined
228+
) => {
229+
props.onSelectSpeaker(props.speakers[index ?? 0]);
230+
}}
231+
onRenderTitle={(props?: IDropdownOption[]) => onRenderTitle('Speaker', props)}
232+
/>
233+
);
234+
235+
const SafariBrowserSpeakerDropdownTrampoline = (): JSX.Element => {
236+
/* @conditional-compile-remove(unsupported-browser) */
237+
if (isSafariWithNoSpeakers) {
238+
return <></>;
239+
}
240+
return speakerDropdown;
241+
};
242+
212243
return (
213244
<Stack data-ui-id="call-composite-device-settings" tokens={mainStackTokens}>
214245
{roleCanUseCamera && (
@@ -262,22 +293,7 @@ export const LocalDeviceSettings = (props: LocalDeviceSettingsType): JSX.Element
262293
/* @conditional-compile-remove(call-readiness) */
263294
onClickEnableDevicePermission={props.onClickEnableDevicePermission}
264295
/>
265-
<Dropdown
266-
aria-labelledby={'call-composite-local-sound-settings-label'}
267-
placeholder={hasSpeakers ? defaultPlaceHolder : noSpeakersLabel}
268-
styles={dropDownStyles(theme)}
269-
disabled={props.speakers.length === 0}
270-
options={getDropDownList(props.speakers)}
271-
defaultSelectedKey={props.selectedSpeaker ? props.selectedSpeaker.id : defaultDeviceId(props.speakers)}
272-
onChange={(
273-
event: React.FormEvent<HTMLDivElement>,
274-
option?: IDropdownOption | undefined,
275-
index?: number | undefined
276-
) => {
277-
props.onSelectSpeaker(props.speakers[index ?? 0]);
278-
}}
279-
onRenderTitle={(props?: IDropdownOption[]) => onRenderTitle('Speaker', props)}
280-
/>
296+
<SafariBrowserSpeakerDropdownTrampoline />
281297
</Stack>
282298
</Stack>
283299
</Stack>

packages/react-composites/src/composites/CallComposite/pages/ConfigurationPage.tsx

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ import { localVideoSelector } from '../../CallComposite/selectors/localVideoStre
6060
/* @conditional-compile-remove(capabilities) */
6161
import { CapabilitiesChangeNotificationBarProps } from '../components/CapabilitiesChangedNotificationBar';
6262
import { SvgWithWordWrapping } from '../components/SvgWithWordWrapping';
63+
import { EnvironmentInfo } from '@azure/communication-calling';
6364

6465
/**
6566
* @private
@@ -362,7 +363,18 @@ export const ConfigurationPage = (props: ConfigurationPageProps): JSX.Element =>
362363
)}
363364
<Stack styles={mobileView ? undefined : configurationSectionStyle}>
364365
{!mobileWithPreview && (
365-
<Stack className={mobileView ? undefined : selectionContainerStyle(theme)}>
366+
<Stack
367+
className={
368+
mobileView
369+
? undefined
370+
: selectionContainerStyle(
371+
theme,
372+
isSafariBrowserEnvironmentTrampoline(
373+
/* @conditional-compile-remove(unsupported-browser) */ environmentInfo
374+
)
375+
)
376+
}
377+
>
366378
<LocalDeviceSettings
367379
{...options}
368380
{...localDeviceSettingsHandlers}
@@ -456,3 +468,10 @@ const Logo = (props: { logo?: { url: string; alt?: string; shape?: 'unset' | 'ci
456468
}
457469
return <Image styles={logoStyles(props.logo.shape)} src={props.logo.url} alt={props.logo.alt} />;
458470
};
471+
472+
const isSafariBrowserEnvironmentTrampoline = (environmentInfo?: EnvironmentInfo): boolean | undefined => {
473+
/* @conditional-compile-remove(unsupported-browser) */
474+
return environmentInfo && environmentInfo?.environment.browser.toLowerCase() === 'safari';
475+
476+
return false;
477+
};

packages/react-composites/src/composites/CallComposite/styles/CallConfiguration.styles.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,10 @@ export const configurationSectionStyle: IStackStyles = {
9191
/**
9292
* @private
9393
*/
94-
export const selectionContainerStyle = (theme: ITheme): string =>
94+
export const selectionContainerStyle = (theme: ITheme, noSpeakerDropdownShown?: boolean): string =>
9595
mergeStyles({
9696
width: '100%',
97-
height: `${CONFIGURATION_PAGE_SECTION_HEIGHT_REM}rem`,
97+
height: noSpeakerDropdownShown ? 'auto' : `${CONFIGURATION_PAGE_SECTION_HEIGHT_REM}rem`,
9898
padding: '1rem',
9999
borderRadius: theme.effects.roundedCorner6,
100100
border: `0.0625rem solid ${theme.palette.neutralLight}`,

0 commit comments

Comments
 (0)