Skip to content

Commit 46b58ed

Browse files
committed
Merge branch 'main' into mgamis/horizontal-gallery-ui-tests
2 parents 1e6a9bd + f5bf4b7 commit 46b58ed

108 files changed

Lines changed: 67 additions & 16 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "prerelease",
3+
"comment": "Logic introduced to cause local camera switcher to appear on mobile.",
4+
"packageName": "@internal/react-components",
5+
"email": "94866715+dmceachernmsft@users.noreply.github.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": "prerelease",
3+
"comment": "Logic introduced to media gallery to allow for mobile detection for local camera switcher.",
4+
"packageName": "@internal/react-composites",
5+
"email": "94866715+dmceachernmsft@users.noreply.github.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": "none",
3+
"comment": "Remove safari from android listing",
4+
"packageName": "@internal/storybook",
5+
"email": "2684369+JamesBurnside@users.noreply.github.com",
6+
"dependentChangeType": "none"
7+
}

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

Lines changed: 1 addition & 0 deletions

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

Lines changed: 1 addition & 0 deletions

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

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ import { LocalScreenShare } from './VideoGallery/LocalScreenShare';
4747
import { RemoteScreenShare } from './VideoGallery/RemoteScreenShare';
4848
import { VideoTile } from './VideoTile';
4949
import { useId } from '@fluentui/react-hooks';
50+
/* @conditional-compile-remove-from(stable) Local_Camera_switcher */
51+
import { LocalVideoCameraCycleButton } from './VideoGallery/LocalVideoCameraCycleButton';
5052

5153
// Currently the Calling JS SDK supports up to 4 remote video streams
5254
const DEFAULT_MAX_REMOTE_VIDEO_STREAMS = 4;
@@ -121,7 +123,11 @@ export interface VideoGalleryProps {
121123
onDisposeRemoteStreamView?: (userId: string) => Promise<void>;
122124
/** Callback to render a particpant avatar */
123125
onRenderAvatar?: OnRenderAvatarCallback;
124-
126+
/* @conditional-compile-remove-from(stable) Local_Camera_switcher */
127+
/**
128+
* Whether to display the local video camera switcher button
129+
*/
130+
showCamerSwitcherInLocalPreview?: boolean;
125131
/**
126132
* Whether to display a mute icon beside the user's display name.
127133
* @defaultValue `true`
@@ -165,7 +171,9 @@ export const VideoGallery = (props: VideoGalleryProps): JSX.Element => {
165171
layout,
166172
onRenderAvatar,
167173
showMuteIndicator,
168-
maxRemoteVideoStreams = DEFAULT_MAX_REMOTE_VIDEO_STREAMS
174+
maxRemoteVideoStreams = DEFAULT_MAX_REMOTE_VIDEO_STREAMS,
175+
/* @conditional-compile-remove-from(stable) Local_Camera_switcher */
176+
showCamerSwitcherInLocalPreview
169177
} = props;
170178

171179
const ids = useIdentifiers();
@@ -227,7 +235,13 @@ export const VideoGallery = (props: VideoGalleryProps): JSX.Element => {
227235
userId={localParticipant.userId}
228236
renderElement={
229237
localVideoStream?.renderElement ? (
230-
<StreamMedia videoStreamElement={localVideoStream.renderElement} />
238+
<>
239+
{
240+
/* @conditional-compile-remove-from(stable) Local_Camera_switcher */
241+
showCamerSwitcherInLocalPreview && <LocalVideoCameraCycleButton />
242+
}
243+
<StreamMedia videoStreamElement={localVideoStream.renderElement} />
244+
</>
231245
) : undefined
232246
}
233247
showLabel={!(shouldFloatLocalVideo && isNarrow)}

packages/react-composites/src/composites/CallComposite/components/LocalVideoCameraButton.tsx renamed to packages/react-components/src/components/VideoGallery/LocalVideoCameraCycleButton.tsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@
33

44
import { IButtonStyles, IconButton } from '@fluentui/react';
55
import React from 'react';
6-
import { OptionsDevice } from '@internal/react-components/src/components/DevicesButton';
6+
import { OptionsDevice } from '../DevicesButton';
77

88
/**
99
* @internal
1010
*/
11-
export interface LocalVideoCameraButtonProps {
11+
export interface LocalVideoCameraCycleButtonProps {
1212
/** Array of cameras available to the user. */
13-
cameras: OptionsDevice[];
13+
cameras?: OptionsDevice[];
1414
/** Currently selected camera in the local video stream. */
15-
currentCamera: OptionsDevice;
15+
currentCamera?: OptionsDevice;
1616
/** callback function to change video feed. */
17-
setCamera: (device: OptionsDevice) => Promise<void>;
17+
setCamera?: (device: OptionsDevice) => Promise<void>;
1818
}
1919

2020
const localVideoCameraCycleButtonStyles: IButtonStyles = {
@@ -29,7 +29,7 @@ const localVideoCameraCycleButtonStyles: IButtonStyles = {
2929
* local video tile camera cycle button - for use on mobile screens only.
3030
* @private
3131
*/
32-
export const LocalVideoCameraCycleButton = (props: LocalVideoCameraButtonProps): JSX.Element => {
32+
export const LocalVideoCameraCycleButton = (props: LocalVideoCameraCycleButtonProps): JSX.Element => {
3333
const { cameras, currentCamera, setCamera } = props;
3434

3535
return (
@@ -41,7 +41,9 @@ export const LocalVideoCameraCycleButton = (props: LocalVideoCameraButtonProps):
4141
if (cameras && currentCamera !== undefined) {
4242
const index = cameras.indexOf(currentCamera);
4343
const newCamera = cameras[(index + 1) % cameras.length];
44-
setCamera(newCamera);
44+
if (setCamera !== undefined) {
45+
setCamera(newCamera);
46+
}
4547
}
4648
}}
4749
/>

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,15 @@ export interface MediaGalleryProps {
3636
onStartLocalVideo: () => Promise<void>;
3737
onRenderAvatar?: OnRenderAvatarCallback;
3838
onFetchAvatarPersonaData?: AvatarPersonaDataCallback;
39+
isMobile?: boolean;
3940
}
4041

4142
/**
4243
* @private
4344
*/
4445
export const MediaGallery = (props: MediaGalleryProps): JSX.Element => {
4546
const videoGalleryProps = usePropsFor(VideoGallery);
46-
4747
useLocalVideoStartTrigger(!!props.isVideoStreamOn);
48-
4948
const VideoGalleryMemoized = useMemo(() => {
5049
return (
5150
<VideoGallery
@@ -54,14 +53,16 @@ export const MediaGallery = (props: MediaGalleryProps): JSX.Element => {
5453
remoteVideoViewOptions={remoteVideoViewOptions}
5554
styles={VideoGalleryStyles}
5655
layout="floatingLocalVideo"
56+
/* @conditional-compile-remove-from(stable) */
57+
showCamerSwitcherInLocalPreview={props.isMobile}
5758
onRenderAvatar={(userId, options) => (
5859
<Stack className={mergeStyles({ position: 'absolute', height: '100%', width: '100%' })}>
5960
<AvatarPersona userId={userId} {...options} dataProvider={props.onFetchAvatarPersonaData} />
6061
</Stack>
6162
)}
6263
/>
6364
);
64-
}, [props.onFetchAvatarPersonaData, videoGalleryProps]);
65+
}, [props.isMobile, props.onFetchAvatarPersonaData, videoGalleryProps]);
6566

6667
return VideoGalleryMemoized;
6768
};

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ export const CallPage = (props: CallPageProps): JSX.Element => {
7373
callStatus === 'Connected' ? (
7474
isNetworkHealthy(networkReconnectTileProps.networkReconnectValue) ? (
7575
<MediaGallery
76+
isMobile={mobileView}
7677
{...mediaGalleryProps}
7778
{...mediaGalleryHandlers}
7879
onRenderAvatar={onRenderAvatar}

0 commit comments

Comments
 (0)