From e7b86b6af479dd87835c13c5be9309521faaa392 Mon Sep 17 00:00:00 2001 From: Kristian Date: Mon, 7 Oct 2024 15:13:14 +0200 Subject: [PATCH 01/35] feat: improvements for the theming scheme of the SDK (#1499) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## ๐ŸŽฏ Goal - Jira Ticket: [PBE-5856](https://stream-io.atlassian.net/browse/PBE-5856) - consolidate and improve the theming options of the SDK ## ๐Ÿ›  Implementation details โœ… theme color and options are improved โœ… new variants added (fontSizes, spacingSizes) โœ… new defaults added โœ… `colorPalette` usages in the SDK are removed โœ… `darkColors` are removed from SDK, so only one set of colors present in base theme โœ… new alternative `theme.get(componentOrPath: string, prop?: keyof Theme['defaults'] | string)` method added with unit test coverage TBD: ๐Ÿšง In the next tasks from the Design v2 provide additional fixes in the dogfood app - [PBE-5855-feat/react-native-video-design-v2](https://github.com/GetStream/stream-video-js/tree/PBE-5855-feat/react-native-video-design-v2) will serve as umbrella branch for tasks which are part of this epic Table with the color name changes for **easier reviewing**: old name | new name | value| ---|---|---| static_white| base1 | palette.grey50 borders | base2 | palette.grey300 text_low_emphasis| base3 | palette.grey500 static_gray | base4|palette.grey700 static_black | base5|palette.grey950 || | dark.conent_bg | background1| palette.grey950 + opacityToHex(0.05) dark_gray |background2| palette.grey800 overlay |background3| palette.grey950 + opacityToHex(0.4) overlay_dark | background4| palette.grey950 + opacityToHex(0.6) dark.bars & dark.controls_bg | background5| palette.grey900 static_overlay | background6| palette.grey950 + opacityToHex(0.85) ||| dark.text_high_emphasis | base1| palette.grey50 dark.borders| base4 | palette.grey700 dark.overlay | background3 | palette.grey950 + opacityToHex(0.4) ## ๐ŸŽจ UI Changes
iOS
Before After
Android
Before After
## ๐Ÿงช Testing ## โ˜‘๏ธ Checklist - [ ] I have signed the [Stream CLA](https://docs.google.com/forms/d/e/1FAIpQLScFKsKkAJI7mhCr7K9rEIOpqIDThrWxuvxnwUq2XkHyG154vQ/viewform) (required) - [ ] PR targets the `develop` branch - [ ] Documentation is updated - [ ] New code is tested in main example apps, including all possible scenarios - [ ] SampleApp iOS and Android - [ ] Expo iOS and Android [PBE-5856]: https://stream-io.atlassian.net/browse/PBE-5856?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ --- .../Call/CallControls/AcceptCallButton.tsx | 2 +- .../Call/CallControls/CallControls.tsx | 2 +- .../Call/CallControls/CallControlsButton.tsx | 6 +- .../Call/CallControls/ChatButton.tsx | 4 +- .../Call/CallControls/HangupCallButton.tsx | 2 +- .../Call/CallControls/ReactionsButton.tsx | 2 +- .../Call/CallControls/RejectCallButton.tsx | 2 +- .../CallControls/ScreenShareToggleButton.tsx | 6 +- .../CallControls/ToggleAudioPreviewButton.tsx | 10 +- .../ToggleAudioPublishingButton.tsx | 6 +- .../CallControls/ToggleCameraFaceButton.tsx | 6 +- .../CallControls/ToggleVideoPreviewButton.tsx | 10 +- .../ToggleVideoPublishingButton.tsx | 6 +- .../CallControls/internal/ReactionsPicker.tsx | 62 ++--- .../Call/CallLayout/CallParticipantsGrid.tsx | 2 +- .../CallLayout/CallParticipantsSpotlight.tsx | 2 +- .../Call/CallTopView/CallTopView.tsx | 6 +- .../CallTopView/ParticipantsInfoBadge.tsx | 6 +- .../components/Call/Lobby/JoinCallButton.tsx | 2 +- .../src/components/Call/Lobby/Lobby.tsx | 10 +- .../src/components/Call/Lobby/LobbyFooter.tsx | 4 +- .../Call/RingingCallContent/IncomingCall.tsx | 6 +- .../Call/RingingCallContent/OutgoingCall.tsx | 6 +- .../RingingCallContent/TextBasedIndicator.tsx | 10 +- .../Call/RingingCallContent/UserInfo.tsx | 2 +- .../HostLivestream/HostLivestream.tsx | 2 +- .../HostLivestreamControls.tsx | 2 +- .../HostStartStreamButton.tsx | 4 +- .../LivestreamAudioControlButton.tsx | 6 +- .../LivestreamScreenShareToggleButton.tsx | 6 +- .../LivestreamVideoControlButton.tsx | 6 +- .../ViewerLeaveStreamButton.tsx | 4 +- .../ViewerLivestreamControls.tsx | 2 +- .../LivestreamLayout/LivestreamLayout.tsx | 2 +- .../LivestreamTopView/DurationBadge.tsx | 8 +- .../LivestreamTopView/FollowerCount.tsx | 8 +- .../HostLivestreamTopView.tsx | 2 +- .../LivestreamTopView/LiveIndicator.tsx | 2 +- .../ViewerLivestreamTopView.tsx | 2 +- .../FloatingParticipantView/index.tsx | 4 +- .../ParticipantView/ParticipantLabel.tsx | 12 +- .../ParticipantNetworkQualityIndicator.tsx | 6 +- .../ParticipantVideoFallback.tsx | 4 +- .../src/components/utility/Avatar.tsx | 2 +- .../components/utility/ScreenShareOverlay.tsx | 10 +- packages/react-native-sdk/src/theme/colors.ts | 112 ++++++--- .../react-native-sdk/src/theme/constants.ts | 51 +++++ packages/react-native-sdk/src/theme/index.ts | 9 +- packages/react-native-sdk/src/theme/theme.ts | 68 ++++-- packages/react-native-sdk/src/theme/types.ts | 89 ++++++-- .../react-native/dogfood/ios/Podfile.lock | 2 +- .../dogfood/src/components/Button.tsx | 49 ++-- .../src/components/ParticipantActions.tsx | 149 ++++++------ .../src/components/ParticipantsInfoList.tsx | 216 +++++++++--------- .../src/screens/Meeting/ChatScreen.tsx | 50 ++-- sample-apps/react-native/dogfood/src/theme.ts | 1 + 56 files changed, 634 insertions(+), 438 deletions(-) diff --git a/packages/react-native-sdk/src/components/Call/CallControls/AcceptCallButton.tsx b/packages/react-native-sdk/src/components/Call/CallControls/AcceptCallButton.tsx index 4eeab20f43..f9bf774c49 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/AcceptCallButton.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/AcceptCallButton.tsx @@ -61,7 +61,7 @@ export const AcceptCallButton = ({ size={buttonSizes.lg} style={acceptCallButton} > - + ); }; diff --git a/packages/react-native-sdk/src/components/Call/CallControls/CallControls.tsx b/packages/react-native-sdk/src/components/Call/CallControls/CallControls.tsx index 6033525a77..540ee1b718 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/CallControls.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/CallControls.tsx @@ -40,7 +40,7 @@ export const CallControls = ({ [ styles.container, { - backgroundColor: disabled - ? colors.disabled - : colorProp || colors.static_white, + backgroundColor: disabled ? colors.disabled : colorProp || colors.base1, opacity: pressed ? 0.2 : 1, height: size || buttonSizes.sm, width: size || buttonSizes.sm, borderRadius: (size || buttonSizes.sm) / 2, - borderColor: colors.content_bg, + borderColor: colors.background1, }, styleProp?.container ?? null, container, diff --git a/packages/react-native-sdk/src/components/Call/CallControls/ChatButton.tsx b/packages/react-native-sdk/src/components/Call/CallControls/ChatButton.tsx index c980227458..66a0bda86c 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/ChatButton.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/ChatButton.tsx @@ -36,7 +36,7 @@ export const ChatButton = ({ return ( - + ); }; @@ -63,7 +63,7 @@ const UnreadBadgeCountIndicator = ({ diff --git a/packages/react-native-sdk/src/components/Call/CallControls/HangupCallButton.tsx b/packages/react-native-sdk/src/components/Call/CallControls/HangupCallButton.tsx index cd9d5513ec..277b42ca6f 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/HangupCallButton.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/HangupCallButton.tsx @@ -72,7 +72,7 @@ export const HangUpCallButton = ({ size={size} testID={ButtonTestIds.HANG_UP_CALL} > - + ); }; diff --git a/packages/react-native-sdk/src/components/Call/CallControls/ReactionsButton.tsx b/packages/react-native-sdk/src/components/Call/CallControls/ReactionsButton.tsx index 03d406d61a..34b8ef5b65 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/ReactionsButton.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/ReactionsButton.tsx @@ -71,7 +71,7 @@ export const ReactionsButton = ({ onPress={reactionsButtonHandler} onLayout={onReactionsButtonLayout} > - + {showReactionsPicker && ( diff --git a/packages/react-native-sdk/src/components/Call/CallControls/RejectCallButton.tsx b/packages/react-native-sdk/src/components/Call/CallControls/RejectCallButton.tsx index f97c930146..f1a3c5372b 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/RejectCallButton.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/RejectCallButton.tsx @@ -69,7 +69,7 @@ export const RejectCallButton = ({ // svgContainerStyle={theme.icon.lg} style={rejectCallButton} > - + ); }; diff --git a/packages/react-native-sdk/src/components/Call/CallControls/ScreenShareToggleButton.tsx b/packages/react-native-sdk/src/components/Call/CallControls/ScreenShareToggleButton.tsx index d9a70c8a9a..ed9480fa35 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/ScreenShareToggleButton.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/ScreenShareToggleButton.tsx @@ -48,16 +48,16 @@ export const ScreenShareToggleButton = ({ return ( {hasPublishedScreenShare ? ( - + ) : ( - + )} {Platform.OS === 'ios' && ( diff --git a/packages/react-native-sdk/src/components/Call/CallControls/ToggleAudioPreviewButton.tsx b/packages/react-native-sdk/src/components/Call/CallControls/ToggleAudioPreviewButton.tsx index 0d6482d7aa..3a30741189 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/ToggleAudioPreviewButton.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/ToggleAudioPreviewButton.tsx @@ -42,22 +42,20 @@ export const ToggleAudioPreviewButton = ({ return ( {!optimisticIsMute ? ( - + ) : ( - + )} ); diff --git a/packages/react-native-sdk/src/components/Call/CallControls/ToggleAudioPublishingButton.tsx b/packages/react-native-sdk/src/components/Call/CallControls/ToggleAudioPublishingButton.tsx index ab1d01faec..c0aed84ee3 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/ToggleAudioPublishingButton.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/ToggleAudioPublishingButton.tsx @@ -41,13 +41,13 @@ export const ToggleAudioPublishingButton = ({ {!optimisticIsMute ? ( - + ) : ( - + )} diff --git a/packages/react-native-sdk/src/components/Call/CallControls/ToggleCameraFaceButton.tsx b/packages/react-native-sdk/src/components/Call/CallControls/ToggleCameraFaceButton.tsx index 68c99ec396..fa5652f665 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/ToggleCameraFaceButton.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/ToggleCameraFaceButton.tsx @@ -47,15 +47,15 @@ export const ToggleCameraFaceButton = ({ diff --git a/packages/react-native-sdk/src/components/Call/CallControls/ToggleVideoPreviewButton.tsx b/packages/react-native-sdk/src/components/Call/CallControls/ToggleVideoPreviewButton.tsx index 28e519614e..f3da81b65e 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/ToggleVideoPreviewButton.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/ToggleVideoPreviewButton.tsx @@ -47,22 +47,20 @@ export const ToggleVideoPreviewButton = ({ return ( {!optimisticIsMute ? ( - ); diff --git a/packages/react-native-sdk/src/components/Call/CallControls/ToggleVideoPublishingButton.tsx b/packages/react-native-sdk/src/components/Call/CallControls/ToggleVideoPublishingButton.tsx index 6486e48de7..a2441a0ce3 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/ToggleVideoPublishingButton.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/ToggleVideoPublishingButton.tsx @@ -45,12 +45,12 @@ export const ToggleVideoPublishingButton = ({ {!optimisticIsMute ? ( - diff --git a/packages/react-native-sdk/src/components/Call/CallControls/internal/ReactionsPicker.tsx b/packages/react-native-sdk/src/components/Call/CallControls/internal/ReactionsPicker.tsx index c86ac1c241..c7d1b683f9 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/internal/ReactionsPicker.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/internal/ReactionsPicker.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useRef } from 'react'; +import React, { useEffect, useMemo, useRef } from 'react'; import { LayoutRectangle, Pressable, @@ -18,20 +18,20 @@ type ReactionPickerProps = Pick & { onRequestedClose: () => void; }; -const TOP_PADDING = 4; -const REACTION_MARGIN_BOTTOM = 4; - export const ReactionsPicker = ({ supportedReactions = defaultEmojiReactions, reactionsButtonLayoutRectangle, onRequestedClose, }: ReactionPickerProps) => { const { - theme: { colors, reactionsPicker }, + theme: { colors, reactionsPicker, variants }, } = useTheme(); + const styles = useStyles(); const call = useCall(); const size = reactionsButtonLayoutRectangle?.width ?? 0; const reactionItemSize = size * 0.8; + const TOP_PADDING = variants.spacingSizes.xs; + const REACTION_MARGIN_BOTTOM = variants.spacingSizes.xs; const popupHeight = // the top padding @@ -104,7 +104,7 @@ export const ReactionsPicker = ({ styles.reactionsPopup, reactionsPopupStyle, { - backgroundColor: colors.static_grey, + backgroundColor: colors.base4, }, reactionsPicker.reactionsPopup, ]} @@ -120,8 +120,7 @@ export const ReactionsPicker = ({ styles.reactionItem, reactionItemStyle, { - // temporary background color until we have theming - backgroundColor: colors.overlay, + backgroundColor: colors.background3, }, reactionsPicker.reactionItem, ]} @@ -159,7 +158,7 @@ export const ReactionsPicker = ({ style={[ reactionsButtonDimmerStyle, { - backgroundColor: colors.static_grey, + backgroundColor: colors.base4, }, reactionsPicker.reactionsButtonDimmer, ]} @@ -169,22 +168,29 @@ export const ReactionsPicker = ({ ); }; -const styles = StyleSheet.create({ - reactionsPopup: { - position: 'absolute', - alignItems: 'center', - paddingTop: TOP_PADDING, - }, - reactionsButtonDimmer: { - position: 'absolute', - opacity: 0.5, - }, - reactionItem: { - alignItems: 'center', - justifyContent: 'center', - marginBottom: REACTION_MARGIN_BOTTOM, - }, - reactionText: { - fontSize: 18.5, - }, -}); +const useStyles = () => { + const { theme } = useTheme(); + return useMemo( + () => + StyleSheet.create({ + reactionsPopup: { + position: 'absolute', + alignItems: 'center', + paddingTop: theme.variants.spacingSizes.xs, + }, + reactionsButtonDimmer: { + position: 'absolute', + opacity: 0.5, + }, + reactionItem: { + alignItems: 'center', + justifyContent: 'center', + marginBottom: theme.variants.spacingSizes.xs, + }, + reactionText: { + fontSize: 18.5, + }, + }), + [theme] + ); +}; diff --git a/packages/react-native-sdk/src/components/Call/CallLayout/CallParticipantsGrid.tsx b/packages/react-native-sdk/src/components/Call/CallLayout/CallParticipantsGrid.tsx index 022f86a400..521f73fc24 100644 --- a/packages/react-native-sdk/src/components/Call/CallLayout/CallParticipantsGrid.tsx +++ b/packages/react-native-sdk/src/components/Call/CallLayout/CallParticipantsGrid.tsx @@ -100,7 +100,7 @@ export const CallParticipantsGrid = ({ style={[ styles.container, landscapeStyles, - { backgroundColor: colors.dark_gray }, + { backgroundColor: colors.background2 }, callParticipantsGrid.container, ]} testID={ComponentTestIds.CALL_PARTICIPANTS_GRID} diff --git a/packages/react-native-sdk/src/components/Call/CallLayout/CallParticipantsSpotlight.tsx b/packages/react-native-sdk/src/components/Call/CallLayout/CallParticipantsSpotlight.tsx index 231246a106..e58164a908 100644 --- a/packages/react-native-sdk/src/components/Call/CallLayout/CallParticipantsSpotlight.tsx +++ b/packages/react-native-sdk/src/components/Call/CallLayout/CallParticipantsSpotlight.tsx @@ -98,7 +98,7 @@ export const CallParticipantsSpotlight = ({ styles.container, landscapeStyles, { - backgroundColor: colors.dark_gray, + backgroundColor: colors.background2, }, callParticipantsSpotlight.container, ]} diff --git a/packages/react-native-sdk/src/components/Call/CallTopView/CallTopView.tsx b/packages/react-native-sdk/src/components/Call/CallTopView/CallTopView.tsx index 4460425573..19b4993d86 100644 --- a/packages/react-native-sdk/src/components/Call/CallTopView/CallTopView.tsx +++ b/packages/react-native-sdk/src/components/Call/CallTopView/CallTopView.tsx @@ -91,7 +91,7 @@ export const CallTopView = ({ ]} onPress={onBackPressed} > - + )} @@ -99,7 +99,7 @@ export const CallTopView = ({ {title ? ( - + @@ -99,7 +99,7 @@ export const Lobby = ({ @@ -174,7 +174,7 @@ const ParticipantStatus = () => { style={[ styles.participantStatusContainer, { - backgroundColor: colors.static_overlay, + backgroundColor: colors.background6, }, lobby.participantStatusContainer, ]} @@ -182,7 +182,7 @@ const ParticipantStatus = () => { @@ -140,7 +140,7 @@ const Background: React.FunctionComponent<{ diff --git a/packages/react-native-sdk/src/components/Call/RingingCallContent/OutgoingCall.tsx b/packages/react-native-sdk/src/components/Call/RingingCallContent/OutgoingCall.tsx index 2af2143c65..ce70a5ab94 100644 --- a/packages/react-native-sdk/src/components/Call/RingingCallContent/OutgoingCall.tsx +++ b/packages/react-native-sdk/src/components/Call/RingingCallContent/OutgoingCall.tsx @@ -74,7 +74,7 @@ export const OutgoingCall = ({ { @@ -125,7 +125,7 @@ const Background = () => { diff --git a/packages/react-native-sdk/src/components/Call/RingingCallContent/TextBasedIndicator.tsx b/packages/react-native-sdk/src/components/Call/RingingCallContent/TextBasedIndicator.tsx index c65cde778e..d4f1f4de53 100644 --- a/packages/react-native-sdk/src/components/Call/RingingCallContent/TextBasedIndicator.tsx +++ b/packages/react-native-sdk/src/components/Call/RingingCallContent/TextBasedIndicator.tsx @@ -18,7 +18,7 @@ export const TextBasedIndicator = (props: TextBasedIndicatorProps) => { } = useTheme(); return ( - + {props.onBackPress && ( { }, ]} > - + )} {props.text} diff --git a/packages/react-native-sdk/src/components/Call/RingingCallContent/UserInfo.tsx b/packages/react-native-sdk/src/components/Call/RingingCallContent/UserInfo.tsx index 3341747739..74a6c0e1ae 100644 --- a/packages/react-native-sdk/src/components/Call/RingingCallContent/UserInfo.tsx +++ b/packages/react-native-sdk/src/components/Call/RingingCallContent/UserInfo.tsx @@ -109,7 +109,7 @@ export const UserInfo = ({ style={[ styles.name, fontStyleByMembersCount, - { color: colors.static_white }, + { color: colors.base1 }, userInfo.name, ]} > diff --git a/packages/react-native-sdk/src/components/Livestream/HostLivestream/HostLivestream.tsx b/packages/react-native-sdk/src/components/Livestream/HostLivestream/HostLivestream.tsx index 8e20bf1529..b18c4dfe9a 100644 --- a/packages/react-native-sdk/src/components/Livestream/HostLivestream/HostLivestream.tsx +++ b/packages/react-native-sdk/src/components/Livestream/HostLivestream/HostLivestream.tsx @@ -109,7 +109,7 @@ export const HostLivestream = ({ style={[ styles.container, { - backgroundColor: colors.dark_gray, + backgroundColor: colors.background2, }, hostLivestream.container, ]} diff --git a/packages/react-native-sdk/src/components/Livestream/LivestreamControls/HostLivestreamControls.tsx b/packages/react-native-sdk/src/components/Livestream/LivestreamControls/HostLivestreamControls.tsx index c5a904b631..d3a1c35ad8 100644 --- a/packages/react-native-sdk/src/components/Livestream/LivestreamControls/HostLivestreamControls.tsx +++ b/packages/react-native-sdk/src/components/Livestream/LivestreamControls/HostLivestreamControls.tsx @@ -45,7 +45,7 @@ export const HostLivestreamControls = ({ diff --git a/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamAudioControlButton.tsx b/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamAudioControlButton.tsx index fcf460e1c4..2fb2defaed 100644 --- a/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamAudioControlButton.tsx +++ b/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamAudioControlButton.tsx @@ -28,7 +28,7 @@ export const LivestreamAudioControlButton = () => { style={[ styles.container, { - backgroundColor: colors.dark_gray, + backgroundColor: colors.background2, height: buttonSizes.xs, width: buttonSizes.xs, }, @@ -46,9 +46,9 @@ export const LivestreamAudioControlButton = () => { ]} > {!optimisticIsMute ? ( - + ) : ( - + )} diff --git a/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamScreenShareToggleButton.tsx b/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamScreenShareToggleButton.tsx index 75debafb17..18b2b82422 100644 --- a/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamScreenShareToggleButton.tsx +++ b/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamScreenShareToggleButton.tsx @@ -34,7 +34,7 @@ export const LivestreamScreenShareToggleButton = () => { { backgroundColor: hasPublishedScreenShare ? colors.error - : colors.dark_gray, + : colors.background2, height: buttonSizes.xs, width: buttonSizes.xs, }, @@ -52,9 +52,9 @@ export const LivestreamScreenShareToggleButton = () => { ]} > {hasPublishedScreenShare ? ( - + ) : ( - + )} {Platform.OS === 'ios' && ( diff --git a/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamVideoControlButton.tsx b/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamVideoControlButton.tsx index 2b4b5c9071..1f47b71be5 100644 --- a/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamVideoControlButton.tsx +++ b/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamVideoControlButton.tsx @@ -34,7 +34,7 @@ export const LivestreamVideoControlButton = () => { style={[ styles.container, { - backgroundColor: colors.dark_gray, + backgroundColor: colors.background2, height: buttonSizes.xs, width: buttonSizes.xs, }, @@ -52,9 +52,9 @@ export const LivestreamVideoControlButton = () => { ]} > {!optimisticIsMute ? ( - diff --git a/packages/react-native-sdk/src/components/Livestream/LivestreamControls/ViewerLeaveStreamButton.tsx b/packages/react-native-sdk/src/components/Livestream/LivestreamControls/ViewerLeaveStreamButton.tsx index f21ec5b3b9..2ded12c0a6 100644 --- a/packages/react-native-sdk/src/components/Livestream/LivestreamControls/ViewerLeaveStreamButton.tsx +++ b/packages/react-native-sdk/src/components/Livestream/LivestreamControls/ViewerLeaveStreamButton.tsx @@ -60,7 +60,7 @@ export const ViewerLeaveStreamButton = ({ style={[ styles.container, { - backgroundColor: colors.dark_gray, + backgroundColor: colors.background2, }, viewerLeaveStreamButton.container, ]} @@ -79,7 +79,7 @@ export const ViewerLeaveStreamButton = ({ style={[ styles.text, typefaces.subtitleBold, - { color: colors.static_white }, + { color: colors.base1 }, viewerLeaveStreamButton.text, ]} > diff --git a/packages/react-native-sdk/src/components/Livestream/LivestreamControls/ViewerLivestreamControls.tsx b/packages/react-native-sdk/src/components/Livestream/LivestreamControls/ViewerLivestreamControls.tsx index 0aec79c7f2..268fec32d6 100644 --- a/packages/react-native-sdk/src/components/Livestream/LivestreamControls/ViewerLivestreamControls.tsx +++ b/packages/react-native-sdk/src/components/Livestream/LivestreamControls/ViewerLivestreamControls.tsx @@ -36,7 +36,7 @@ export const ViewerLivestreamControls = ({ style={[ styles.container, { - backgroundColor: colors.static_overlay, + backgroundColor: colors.background6, }, viewerLivestreamControls.container, ]} diff --git a/packages/react-native-sdk/src/components/Livestream/LivestreamLayout/LivestreamLayout.tsx b/packages/react-native-sdk/src/components/Livestream/LivestreamLayout/LivestreamLayout.tsx index abc51bcdbd..48725bcf3d 100644 --- a/packages/react-native-sdk/src/components/Livestream/LivestreamLayout/LivestreamLayout.tsx +++ b/packages/react-native-sdk/src/components/Livestream/LivestreamLayout/LivestreamLayout.tsx @@ -80,7 +80,7 @@ export const LivestreamLayout = ({ style={[ styles.container, landScapeStyles, - { backgroundColor: colors.static_grey }, + { backgroundColor: colors.base4 }, livestreamLayout.container, ]} > diff --git a/packages/react-native-sdk/src/components/Livestream/LivestreamTopView/DurationBadge.tsx b/packages/react-native-sdk/src/components/Livestream/LivestreamTopView/DurationBadge.tsx index 53b5830824..c5c0e8a10d 100644 --- a/packages/react-native-sdk/src/components/Livestream/LivestreamTopView/DurationBadge.tsx +++ b/packages/react-native-sdk/src/components/Livestream/LivestreamTopView/DurationBadge.tsx @@ -120,7 +120,7 @@ export const DurationBadge = ({ mode }: DurationBadgeProps) => { @@ -137,11 +137,7 @@ export const DurationBadge = ({ mode }: DurationBadgeProps) => { {formatDuration(duration)} diff --git a/packages/react-native-sdk/src/components/Livestream/LivestreamTopView/FollowerCount.tsx b/packages/react-native-sdk/src/components/Livestream/LivestreamTopView/FollowerCount.tsx index e8b2552d33..5e0435ab2c 100644 --- a/packages/react-native-sdk/src/components/Livestream/LivestreamTopView/FollowerCount.tsx +++ b/packages/react-native-sdk/src/components/Livestream/LivestreamTopView/FollowerCount.tsx @@ -26,7 +26,7 @@ export const FollowerCount = ({}: FollowerCountProps) => { @@ -40,11 +40,7 @@ export const FollowerCount = ({}: FollowerCountProps) => { {totalParticipants} diff --git a/packages/react-native-sdk/src/components/Livestream/LivestreamTopView/HostLivestreamTopView.tsx b/packages/react-native-sdk/src/components/Livestream/LivestreamTopView/HostLivestreamTopView.tsx index f86ab3e734..e923ea7307 100644 --- a/packages/react-native-sdk/src/components/Livestream/LivestreamTopView/HostLivestreamTopView.tsx +++ b/packages/react-native-sdk/src/components/Livestream/LivestreamTopView/HostLivestreamTopView.tsx @@ -57,7 +57,7 @@ export const HostLivestreamTopView = ({ { { ]} > - + ); @@ -171,7 +171,7 @@ export const FloatingParticipantView = ({ styles.participantViewContainer, participantViewStyle, { - shadowColor: colors.static_black, + shadowColor: colors.base5, }, floatingParticipantsView.participantViewContainer, ]} diff --git a/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantLabel.tsx b/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantLabel.tsx index 3244365c41..c1127a022c 100644 --- a/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantLabel.tsx +++ b/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantLabel.tsx @@ -67,7 +67,7 @@ export const ParticipantLabel = ({ - + - + )} diff --git a/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantNetworkQualityIndicator.tsx b/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantNetworkQualityIndicator.tsx index e9438094fd..1e768bcf96 100644 --- a/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantNetworkQualityIndicator.tsx +++ b/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantNetworkQualityIndicator.tsx @@ -29,9 +29,9 @@ const useConnectionQualitySignalColors = ( case SfuModels.ConnectionQuality.EXCELLENT: return [colors.primary, colors.primary, colors.primary]; case SfuModels.ConnectionQuality.GOOD: - return [colors.primary, colors.primary, colors.static_white]; + return [colors.primary, colors.primary, colors.base1]; case SfuModels.ConnectionQuality.POOR: - return [colors.error, colors.static_white, colors.static_white]; + return [colors.error, colors.base1, colors.base1]; default: return null; } @@ -57,7 +57,7 @@ export const ParticipantNetworkQualityIndicator = ({ style={[ styles.container, { - backgroundColor: colors.static_overlay, + backgroundColor: colors.background6, height: iconSizes.lg, width: iconSizes.lg, }, diff --git a/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantVideoFallback.tsx b/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantVideoFallback.tsx index bacf63da1e..1876085007 100644 --- a/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantVideoFallback.tsx +++ b/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantVideoFallback.tsx @@ -30,7 +30,7 @@ export const ParticipantVideoFallback = ({ style={[ styles.container, { - backgroundColor: colors.static_grey, + backgroundColor: colors.base4, }, participantVideoFallback.container, ]} @@ -39,7 +39,7 @@ export const ParticipantVideoFallback = ({ { { @@ -41,7 +41,7 @@ export const ScreenShareOverlay = ({}: ScreenShareOverlayProps) => { style={[ styles.text, typefaces.subtitleBold, - { color: colors.static_white }, + { color: colors.base1 }, screenshareOverlay.text, ]} > @@ -53,7 +53,7 @@ export const ScreenShareOverlay = ({}: ScreenShareOverlayProps) => { return [ styles.button, { - backgroundColor: colors.dark_gray, + backgroundColor: colors.background2, opacity: pressed ? 0.2 : 1, }, screenshareOverlay.button, @@ -67,12 +67,12 @@ export const ScreenShareOverlay = ({}: ScreenShareOverlayProps) => { screenshareOverlay.buttonIcon, ]} > - + diff --git a/packages/react-native-sdk/src/theme/colors.ts b/packages/react-native-sdk/src/theme/colors.ts index 813aa54421..1d09982558 100644 --- a/packages/react-native-sdk/src/theme/colors.ts +++ b/packages/react-native-sdk/src/theme/colors.ts @@ -1,4 +1,5 @@ import { palette } from './constants'; +import { ColorScheme } from './types'; const opacityToHex = (opacity: number) => { return Math.round(opacity * 255) @@ -6,44 +7,81 @@ const opacityToHex = (opacity: number) => { .padStart(2, '0'); }; -const colors = { - primary: palette.blue500, - error: palette.red400, - info: palette.green500, - static_black: palette.grey950, - static_white: palette.grey50, - static_overlay: palette.grey950 + opacityToHex(0.85), - static_grey: palette.grey700, - disabled: palette.grey600, - text_low_emphasis: palette.grey500, - text_high_emphasis: palette.grey950, - controls_bg: palette.grey50, - borders: palette.grey300, - overlay: palette.grey950 + opacityToHex(0.4), - overlay_dark: palette.grey950 + opacityToHex(0.6), - bars: palette.grey50, - content_bg: palette.grey950 + opacityToHex(0.05), - dark_gray: palette.grey800, +const colors: ColorScheme = { + primary: palette.blue500, // remove and replace with primary100 + error: palette.red400, // remove and replace with warning100 + info: palette.green500, // remove and replace with success100 + disabled: palette.grey600, // remove and replace with primary180 + + // these are legacy and should be removed after Design v2 completed + base1: palette.grey50, + base2: palette.grey300, + base3: palette.grey500, + base4: palette.grey700, + base5: palette.grey950, + + // these are legacy and should be removed after Design v2 completed + background1: palette.grey950 + opacityToHex(0.05), + background2: palette.grey800, + background3: palette.grey950 + opacityToHex(0.4), + background4: palette.grey950 + opacityToHex(0.6), + background5: palette.grey900, + background6: palette.grey950 + opacityToHex(0.85), + + buttonPrimaryDefault: '#005fff', + buttonPrimaryDisabled: '#1b2c43', + buttonPrimaryHover: '#4c8fff', + buttonPrimaryPressed: '#123d82', + buttonQuaternaryActive: '#19232d', + buttonQuaternaryDefault: '#dc433b', + buttonQuaternaryDisabled: '#31292f', + buttonQuaternaryHover: '#e77b76', + buttonQuaternaryPressed: '#7d3535', + buttonSecondaryDefault: '#19232d', + buttonSecondaryDisabled: '#1e262e29', + buttonSecondaryHover: '#323b44', + buttonSecondaryPressed: '#101213', + buttonSecondaryActiveDefault: '#005fff', + buttonSecondaryActiveHover: '#4c8fff', + buttonSecondaryActivePressed: '#123d82', + buttonSecondaryWarningDefault: '#dc433b', + buttonSecondaryWarningHover: '#e77b76', + buttonSecondaryWarningPressed: '#7d3535', + buttonTertiaryActive: '#19232d', + buttonTertiaryDisabled: '#1e262e29', + buttonTertiaryHover: '#4c535b', + buttonTertiaryPressed: '#101213', + buttonTertiaryStroke: '#323b44', + containerCaution: '#353830', + containerNeutral: '#323b44', + containerPrimary: '#1b2c43', + containerSecondary: '#263942', + containerSuccess: '#1d2f34', + containerTertiary: '#2d3042', + containerWarning: '#31292f', + iconAlertCaution: '#ffd646', + iconAlertSuccess: '#00e2a1', + iconAlertWarning: '#dc433b', + iconPrimaryAccent: '#005fff', + iconPrimaryDefault: '#eff0f1', + iconPrimaryDisabled: '#7e8389', + iconPrimaryHover: '#e3e4e5', + iconPrimaryOnAccent: '#eff0f1', + iconPrimaryPressed: '#656b72', + sheetOverlay: '#0c0d0ea6', + sheetPrimary: '#000000', + sheetSecondary: '#101213', + sheetTertiary: '#19232d', + typeAccent: '#00e2a1', + typeOnAccent: '#eff0f1', + typePrimary: '#eff0f1', + typeQuaternary: '#101213', + typeSecondary: '#b0b4b7', + typeTertiary: '#656b72', }; -const darkThemeColors = { - primary: palette.blue500, - error: palette.red400, - info: palette.green500, - static_black: palette.grey950, - static_white: palette.grey50, - static_overlay: palette.grey950 + opacityToHex(0.85), - static_grey: palette.grey700, - disabled: palette.grey600, - text_low_emphasis: palette.grey500, - text_high_emphasis: palette.grey50, - controls_bg: palette.grey900, - borders: palette.grey700, - overlay: palette.grey950 + opacityToHex(0.4), - overlay_dark: palette.grey50 + opacityToHex(0.6), - bars: palette.grey900, - content_bg: palette.grey950 + opacityToHex(0.05), - dark_gray: palette.grey800, +const colorPalette = { + colors, }; -export { colors, darkThemeColors }; +export { colorPalette, colors }; diff --git a/packages/react-native-sdk/src/theme/constants.ts b/packages/react-native-sdk/src/theme/constants.ts index 1d9dafe176..c9c99171f5 100644 --- a/packages/react-native-sdk/src/theme/constants.ts +++ b/packages/react-native-sdk/src/theme/constants.ts @@ -1,5 +1,6 @@ const ref = { palette: { + // TODO: remove old palette colors and keep only new ones: primary, secondary... in design v2 green50: '#F6FEF9', green100: '#E9F1FF', green200: '#A6F2C6', @@ -44,6 +45,56 @@ const ref = { grey800: '#1C1E22', grey900: '#121416', grey950: '#080707', + + primary100: '#005fff', + primary150: '#123d82', + primary180: '#1b2c43', + primary20: '#ccdfff', + primary70: '#4c8fff', + + secondary100: '#69e5f6', + secondary140: '#448592', + secondary180: '#263942', + secondary20: '#f0fcfe', + secondary60: '#a5effa', + + tertiary100: '#b38af8', + tertiary170: '#4b446b', + tertiary190: '#2d3042', + tertiary20: '#f7f3fe', + tertiary60: '#d1b9fb', + + success100: '#00e2a1', + success150: '#12715c', + success190: '#1d2f34', + success20: '#e5fcf6', + success60: '#66eec7', + + warning100: '#dc433b', + warning150: '#7d3535', + warning190: '#31292f', + warning20: '#f8d9d8', + warning70: '#e77b76', + + caution100: '#ffd646', + caution150: '#786c38', + caution180: '#353830', + caution20: '#fffbec', + caution60: '#ffe690', + + neutral0: '#eff0f1', + neutral10: '#e3e4e5', + neutral100: '#0d1721', + neutral110: '#101213', + neutral120: '#000000', + neutral20: '#caccce', + neutral30: '#b0b4b7', + neutral40: '#979ca0', + neutral50: '#7e8389', + neutral60: '#656b72', + neutral70: '#4c535b', + neutral80: '#323b44', + neutral90: '#19232d', }, }; diff --git a/packages/react-native-sdk/src/theme/index.ts b/packages/react-native-sdk/src/theme/index.ts index a67a95daf5..50fd821aed 100644 --- a/packages/react-native-sdk/src/theme/index.ts +++ b/packages/react-native-sdk/src/theme/index.ts @@ -1,9 +1,2 @@ -import { colors, darkThemeColors } from './colors'; -import { Theme } from './types'; - -export const colorPallet: Theme = { - light: colors, - dark: darkThemeColors, -}; - export * from './theme'; +export * from './colors'; diff --git a/packages/react-native-sdk/src/theme/theme.ts b/packages/react-native-sdk/src/theme/theme.ts index 2d3008688f..488257cb48 100644 --- a/packages/react-native-sdk/src/theme/theme.ts +++ b/packages/react-native-sdk/src/theme/theme.ts @@ -1,32 +1,28 @@ import { ImageStyle, TextStyle, ViewStyle } from 'react-native/types'; import { colors } from './colors'; -import { ColorScheme, FontStyle, FontTypes } from './types'; +import { ColorScheme, DimensionType, FontStyle, FontTypes } from './types'; +import { ColorValue } from 'react-native'; export type Theme = { variants: { - buttonSizes: { - xs: number; - sm: number; - md: number; - lg: number; - xl: number; - }; - iconSizes: { - xs: number; - sm: number; - md: number; - lg: number; - xl: number; - }; - avatarSizes: { - xs: number; - sm: number; - md: number; - lg: number; - xl: number; - }; + buttonSizes: DimensionType; + iconSizes: DimensionType; + avatarSizes: DimensionType; + fontSizes: DimensionType; + spacingSizes: DimensionType; }; typefaces: Record; + defaults: { + color: ColorValue; + backgroundColor: ColorValue; + margin: number; + padding: number; + fontSize: number; + fontWeight: TextStyle['fontWeight']; + borderRadius: ViewStyle['borderRadius']; + borderColor: ColorValue; + borderWidth: ViewStyle['borderWidth']; + }; colors: ColorScheme; avatar: { container: ViewStyle; @@ -279,6 +275,9 @@ export type Theme = { buttonIcon: ViewStyle; buttonText: TextStyle; }; + + // Index signature for additional dynamic properties + [component: string]: any; }; export const defaultTheme: Theme = { @@ -304,6 +303,20 @@ export const defaultTheme: Theme = { lg: 160, xl: 180, }, + spacingSizes: { + xs: 4, + sm: 8, + md: 16, + lg: 24, + xl: 32, + }, + fontSizes: { + xs: 8, + sm: 12, + md: 16, + lg: 20, + xl: 24, + }, }, typefaces: { heading4: { @@ -335,6 +348,17 @@ export const defaultTheme: Theme = { fontWeight: '400', }, }, + defaults: { + color: colors.primary, + backgroundColor: colors.background2, + margin: 10, + padding: 10, + fontSize: 16, + fontWeight: '500', + borderRadius: 10, + borderColor: colors.primary, + borderWidth: 1, + }, colors: colors, avatar: { container: {}, diff --git a/packages/react-native-sdk/src/theme/types.ts b/packages/react-native-sdk/src/theme/types.ts index 54348cc1a1..d2ba8bf903 100644 --- a/packages/react-native-sdk/src/theme/types.ts +++ b/packages/react-native-sdk/src/theme/types.ts @@ -1,24 +1,77 @@ import { ColorValue, TextStyle } from 'react-native'; -// TODO: check if this is used somewhere and remove if not export type ColorScheme = { primary: ColorValue; error: ColorValue; info: ColorValue; - static_black: ColorValue; - static_white: ColorValue; - static_overlay: ColorValue; - static_grey: ColorValue; disabled: ColorValue; - text_low_emphasis: ColorValue; - text_high_emphasis: ColorValue; - controls_bg: ColorValue; - borders: ColorValue; - overlay: ColorValue; - overlay_dark: ColorValue; - bars: ColorValue; - content_bg: ColorValue; - dark_gray: ColorValue; + + // TODO: remove these legacy colors when Design v2 rewrite is completed + base1: ColorValue; + base2: ColorValue; + base4: ColorValue; + base5: ColorValue; + + // TODO: remove these legacy colors when Design v2 rewrite is completed + background1: ColorValue; + background2: ColorValue; + background3: ColorValue; + background4: ColorValue; + background5: ColorValue; + background6: ColorValue; + + // TODO: when design v2 is complete, filter out the not used colors from here (expected to have ~15 theme colors) + buttonPrimaryDefault: ColorValue; + buttonPrimaryDisabled: ColorValue; + buttonPrimaryHover: ColorValue; + buttonPrimaryPressed: ColorValue; + buttonQuaternaryActive: ColorValue; + buttonQuaternaryDefault: ColorValue; + buttonQuaternaryDisabled: ColorValue; + buttonQuaternaryHover: ColorValue; + buttonQuaternaryPressed: ColorValue; + buttonSecondaryDefault: ColorValue; + buttonSecondaryDisabled: ColorValue; + buttonSecondaryHover: ColorValue; + buttonSecondaryPressed: ColorValue; + buttonSecondaryActiveDefault: ColorValue; + buttonSecondaryActiveHover: ColorValue; + buttonSecondaryActivePressed: ColorValue; + buttonSecondaryWarningDefault: ColorValue; + buttonSecondaryWarningHover: ColorValue; + buttonSecondaryWarningPressed: ColorValue; + buttonTertiaryActive: ColorValue; + buttonTertiaryDisabled: ColorValue; + buttonTertiaryHover: ColorValue; + buttonTertiaryPressed: ColorValue; + buttonTertiaryStroke: ColorValue; + containerCaution: ColorValue; + containerNeutral: ColorValue; + containerPrimary: ColorValue; + containerSecondary: ColorValue; + containerSuccess: ColorValue; + containerTertiary: ColorValue; + containerWarning: ColorValue; + iconAlertCaution: ColorValue; + iconAlertSuccess: ColorValue; + iconAlertWarning: ColorValue; + iconPrimaryAccent: ColorValue; + iconPrimaryDefault: ColorValue; + iconPrimaryDisabled: ColorValue; + iconPrimaryHover: ColorValue; + iconPrimaryOnAccent: ColorValue; + iconPrimaryPressed: ColorValue; + sheetOverlay: ColorValue; + sheetPrimary: ColorValue; + sheetSecondary: ColorValue; + sheetTertiary: ColorValue; + typeAccent: ColorValue; + typeOnAccent: ColorValue; + typePrimary: ColorValue; + typeQuaternary: ColorValue; + typeSecondary: ColorValue; + typeTertiary: ColorValue; + // allow any other color [key: string]: ColorValue; }; @@ -38,6 +91,14 @@ export type FontStyle = { fontWeight: TextStyle['fontWeight']; }; +export type DimensionType = { + xs: number; + sm: number; + md: number; + lg: number; + xl: number; +}; + export type FontsScheme = Record; export type Theme = ColorType; diff --git a/sample-apps/react-native/dogfood/ios/Podfile.lock b/sample-apps/react-native/dogfood/ios/Podfile.lock index 6280c8de9d..d95247de93 100644 --- a/sample-apps/react-native/dogfood/ios/Podfile.lock +++ b/sample-apps/react-native/dogfood/ios/Podfile.lock @@ -1485,4 +1485,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: f96321cd21f8fa84788658bc6649718343f705b3 -COCOAPODS: 1.14.3 +COCOAPODS: 1.15.2 diff --git a/sample-apps/react-native/dogfood/src/components/Button.tsx b/sample-apps/react-native/dogfood/src/components/Button.tsx index d34e26fb7b..21f7a7b4a1 100644 --- a/sample-apps/react-native/dogfood/src/components/Button.tsx +++ b/sample-apps/react-native/dogfood/src/components/Button.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useMemo } from 'react'; import { Pressable, PressableProps, @@ -8,8 +8,8 @@ import { TextStyle, ViewStyle, } from 'react-native'; -import { appTheme } from '../theme'; import { BUTTON_HEIGHT } from '../constants'; +import { useTheme } from '@stream-io/video-react-native-sdk'; type ButtonPropTypes = Omit & { title: string; @@ -24,6 +24,8 @@ export const Button = ({ titleStyle, ...rest }: ButtonPropTypes) => { + const styles = useStyles(); + return ( { + const { theme } = useTheme(); + return useMemo( + () => + StyleSheet.create({ + button: { + backgroundColor: theme.colors.primary, + justifyContent: 'center', + borderRadius: 8, + height: BUTTON_HEIGHT, + paddingHorizontal: theme.variants.spacingSizes.md, + }, + buttonText: { + color: theme.colors.static_white, + fontWeight: theme.typefaces.heading6.fontWeight, + textAlign: 'center', + fontSize: 17, + }, + disabledButtonStyle: { + backgroundColor: theme.colors.disabled, + }, + }), + [theme], + ); +}; diff --git a/sample-apps/react-native/dogfood/src/components/ParticipantActions.tsx b/sample-apps/react-native/dogfood/src/components/ParticipantActions.tsx index 7385512955..7b45e84436 100644 --- a/sample-apps/react-native/dogfood/src/components/ParticipantActions.tsx +++ b/sample-apps/react-native/dogfood/src/components/ParticipantActions.tsx @@ -1,6 +1,5 @@ import { Avatar, - colorPallet, hasAudio, hasVideo, OwnCapability, @@ -18,8 +17,9 @@ import { Video } from '../assets/Video'; import { VideoDisabled } from '../assets/VideoDisabled'; import { VideoSlash } from '../assets/VideoSlash'; import { Pressable, StyleSheet, Text, View } from 'react-native'; -import React, { useCallback } from 'react'; +import React, { useCallback, useMemo } from 'react'; import { generateParticipantTitle } from '../utils'; +import { useTheme } from 'stream-chat-react-native'; type CallParticipantOptionType = { title: string; @@ -37,6 +37,10 @@ type ParticipantActionsType = { export const ParticipantActions = (props: ParticipantActionsType) => { const { participant, setSelectedParticipant } = props; const call = useCall(); + const { + theme: { colors }, + } = useTheme(); + const styles = useStyles(); const { t } = useI18n(); const { useHasPermissions } = useCallStateHooks(); const userHasMuteUsersCapability = useHasPermissions( @@ -99,7 +103,7 @@ export const ParticipantActions = (props: ParticipantActionsType) => { const muteUserVideoOption = participantPublishesVideo ? { - icon: , + icon: , title: 'Mute Video', onPressHandler: muteUserVideo, } @@ -107,7 +111,7 @@ export const ParticipantActions = (props: ParticipantActionsType) => { const muteUserAudioOption = participantPublishesAudio ? { - icon: , + icon: , title: 'Mute Audio', onPressHandler: muteUserAudio, } @@ -121,37 +125,37 @@ export const ParticipantActions = (props: ParticipantActionsType) => { userHasUpdateCallPermissionsCapability ? [ { - icon: , + icon: , title: 'Disable Video', onPressHandler: async () => await revokePermission(OwnCapability.SEND_VIDEO), }, { - icon: , + icon: , title: 'Disable Audio', onPressHandler: async () => await revokePermission(OwnCapability.SEND_AUDIO), }, { - icon: , + icon: , title: 'Allow Audio', onPressHandler: async () => await grantPermission(OwnCapability.SEND_AUDIO), }, { - icon: {options.map((option, index) => { @@ -234,59 +238,66 @@ export const ParticipantActions = (props: ParticipantActionsType) => { ); }; -const styles = StyleSheet.create({ - outerContainer: { - justifyContent: 'center', - flex: 1, - }, - modalContainer: { - backgroundColor: colorPallet.dark.bars, - borderRadius: 15, - marginHorizontal: 32, - }, - participantInfo: { - flexDirection: 'row', - justifyContent: 'space-between', - alignItems: 'flex-start', - padding: 12, - }, - userInfo: { - flexDirection: 'row', - alignItems: 'center', - }, - name: { - marginLeft: 8, - fontSize: 16, - fontWeight: '500', - color: colorPallet.dark.text_high_emphasis, - }, - option: { - paddingHorizontal: 24, - paddingVertical: 12, - flexDirection: 'row', - alignItems: 'center', - }, - iconContainer: { - height: 20, - width: 20, - }, - title: { - marginLeft: 16, - color: colorPallet.dark.text_high_emphasis, - fontSize: 16, - fontWeight: '400', - }, - borderBottom: { - borderBottomColor: colorPallet.dark.borders, - borderBottomWidth: 1, - }, - crossIcon: { - height: 15, - width: 15, - }, - closePressable: { - padding: 8, - borderRadius: 5, - backgroundColor: colorPallet.light.static_grey, - }, -}); +const useStyles = () => { + const { theme } = useTheme(); + return useMemo( + () => + StyleSheet.create({ + outerContainer: { + justifyContent: 'center', + flex: 1, + }, + modalContainer: { + backgroundColor: theme.colors.background5, + borderRadius: 15, + marginHorizontal: 32, + }, + participantInfo: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'flex-start', + padding: 12, + }, + userInfo: { + flexDirection: 'row', + alignItems: 'center', + }, + name: { + marginLeft: 8, + fontSize: 16, + fontWeight: '500', + color: theme.colors.base1, + }, + option: { + paddingHorizontal: 24, + paddingVertical: 12, + flexDirection: 'row', + alignItems: 'center', + }, + iconContainer: { + height: 20, + width: 20, + }, + title: { + marginLeft: 16, + color: theme.colors.base1, + fontSize: 16, + fontWeight: '400', + }, + borderBottom: { + borderBottomColor: theme.colors.base4, + borderBottomWidth: 1, + }, + crossIcon: { + height: 15, + width: 15, + }, + closePressable: { + padding: 8, + borderRadius: 5, + backgroundColor: theme.colors.base4, + }, + }), + [theme], + ); +}; diff --git a/sample-apps/react-native/dogfood/src/components/ParticipantsInfoList.tsx b/sample-apps/react-native/dogfood/src/components/ParticipantsInfoList.tsx index 13923e5ebd..8fe4964efa 100644 --- a/sample-apps/react-native/dogfood/src/components/ParticipantsInfoList.tsx +++ b/sample-apps/react-native/dogfood/src/components/ParticipantsInfoList.tsx @@ -1,7 +1,6 @@ -import React, { useCallback, useState } from 'react'; +import React, { useCallback, useMemo, useState } from 'react'; import { Avatar, - colorPallet, hasAudio, hasScreenShare, hasVideo, @@ -12,6 +11,7 @@ import { useCallStateHooks, useConnectedUser, useI18n, + useTheme, } from '@stream-io/video-react-native-sdk'; import { Alert, @@ -57,6 +57,7 @@ export const ParticipantsInfoList = ({ isCallParticipantsInfoVisible, setIsCallParticipantsInfoVisible, }: ParticipantsInfoListProps) => { + const styles = useStyles(); const { useParticipants } = useCallStateHooks(); const participants = useParticipants(); const { t } = useI18n(); @@ -178,6 +179,10 @@ type ParticipantInfoType = { }; const ParticipantInfoItem = (props: ParticipantInfoType) => { + const { + theme: { colors }, + } = useTheme(); + const styles = useStyles(); const { participant, setSelectedParticipant } = props; const connectedUser = useConnectedUser(); const participantIsLocalParticipant = @@ -212,22 +217,22 @@ const ParticipantInfoItem = (props: ParticipantInfoType) => { - + )} {isAudioMuted && ( - + )} {isVideoMuted && ( - + )} {!participantIsLocalParticipant && ( - + )} @@ -235,99 +240,106 @@ const ParticipantInfoItem = (props: ParticipantInfoType) => { ); }; -const styles = StyleSheet.create({ - backDropBackground: { - ...StyleSheet.absoluteFillObject, - backgroundColor: colorPallet.dark.overlay, - zIndex: Z_INDEX.IN_BACK, - }, - content: { - zIndex: Z_INDEX.IN_FRONT, - backgroundColor: colorPallet.dark.bars, - borderRadius: 15, - marginHorizontal: 16, - }, - header: { - flexDirection: 'row', - justifyContent: 'space-between', - alignItems: 'center', - paddingVertical: 12, - }, - leftHeaderElement: { - marginLeft: 16, - }, - headerText: { - fontSize: 16, - fontWeight: '600', - color: colorPallet.dark.text_high_emphasis, - }, - closePressable: { - padding: 8, - borderRadius: 5, - marginRight: 16, - backgroundColor: colorPallet.light.static_grey, - }, - buttonGroup: { - flexDirection: 'row', - justifyContent: 'space-between', - paddingVertical: 12, - paddingHorizontal: 4, - }, - screenShareIconContainer: { - height: 25, - width: 25, - }, - genericIconContainer: { - height: 20, - width: 20, - }, - crossIcon: { - height: 15, - width: 15, - }, - button: { - flex: 1, - backgroundColor: colorPallet.dark.primary, - borderRadius: 24, - padding: 8, - marginHorizontal: 8, - }, - buttonText: { - textAlign: 'center', - color: colorPallet.dark.static_white, - fontSize: 16, - fontWeight: '500', - }, - participant: { - paddingHorizontal: 8, - paddingVertical: 4, - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'space-between', - borderBottomColor: colorPallet.dark.borders, - borderBottomWidth: 1, - }, - participantInfo: { - flexDirection: 'row', - alignItems: 'center', - flexShrink: 1, - }, - name: { - marginLeft: 8, - color: colorPallet.dark.text_high_emphasis, - flexShrink: 1, - fontSize: 16, - fontWeight: '500', - }, - icons: { - flexDirection: 'row', - }, - svgContainerStyle: { - marginLeft: 8, - }, - modal: { - alignItems: 'center', - justifyContent: 'center', - backgroundColor: colorPallet.dark.overlay, - }, -}); +const useStyles = () => { + const { theme } = useTheme(); + return useMemo( + () => + StyleSheet.create({ + backDropBackground: { + ...StyleSheet.absoluteFillObject, + backgroundColor: theme.colors.background3, + zIndex: Z_INDEX.IN_BACK, + }, + content: { + zIndex: Z_INDEX.IN_FRONT, + backgroundColor: theme.colors.background5, + borderRadius: 15, + marginHorizontal: 16, + }, + header: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + paddingVertical: 12, + }, + leftHeaderElement: { + marginLeft: 16, + }, + headerText: { + fontSize: 16, + fontWeight: '600', + color: theme.base1, + }, + closePressable: { + padding: 8, + borderRadius: 5, + marginRight: 16, + backgroundColor: theme.base4, + }, + buttonGroup: { + flexDirection: 'row', + justifyContent: 'space-between', + paddingVertical: 12, + paddingHorizontal: 4, + }, + screenShareIconContainer: { + height: 25, + width: 25, + }, + genericIconContainer: { + height: 20, + width: 20, + }, + crossIcon: { + height: 15, + width: 15, + }, + button: { + flex: 1, + backgroundColor: theme.colors.primary, + borderRadius: 24, + padding: 8, + marginHorizontal: 8, + }, + buttonText: { + textAlign: 'center', + color: theme.colors.base1, + fontSize: 16, + fontWeight: '500', + }, + participant: { + paddingHorizontal: 8, + paddingVertical: 4, + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + borderBottomColor: theme.colors.base4, + borderBottomWidth: 1, + }, + participantInfo: { + flexDirection: 'row', + alignItems: 'center', + flexShrink: 1, + }, + name: { + marginLeft: 8, + color: theme.colors.base1, + flexShrink: 1, + fontSize: 16, + fontWeight: '500', + }, + icons: { + flexDirection: 'row', + }, + svgContainerStyle: { + marginLeft: 8, + }, + modal: { + alignItems: 'center', + justifyContent: 'center', + backgroundColor: theme.colors.background3, + }, + }), + [theme], + ); +}; diff --git a/sample-apps/react-native/dogfood/src/screens/Meeting/ChatScreen.tsx b/sample-apps/react-native/dogfood/src/screens/Meeting/ChatScreen.tsx index c9f2afa845..c1dad33220 100644 --- a/sample-apps/react-native/dogfood/src/screens/Meeting/ChatScreen.tsx +++ b/sample-apps/react-native/dogfood/src/screens/Meeting/ChatScreen.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useMemo, useState } from 'react'; import { Pressable, SafeAreaView, StyleSheet, Text, View } from 'react-native'; import { Channel, @@ -10,7 +10,7 @@ import { AuthenticationProgress } from '../../components/AuthenticatingProgress' import { Channel as ChannelType } from 'stream-chat'; import { MeetingStackParamList, StreamChatGenerics } from '../../../types'; import { NativeStackScreenProps } from '@react-navigation/native-stack'; -import { colorPallet, useI18n } from '@stream-io/video-react-native-sdk'; +import { useI18n, useTheme } from '@stream-io/video-react-native-sdk'; import { useAppGlobalStoreSetState, useAppGlobalStoreValue, @@ -22,6 +22,7 @@ type ChatScreenProps = NativeStackScreenProps< >; const ChannelHeader = () => { + const styles = useStyles(); const chatLabelNoted = useAppGlobalStoreValue( (store) => store.chatLabelNoted, ); @@ -87,22 +88,29 @@ export const ChatScreen = ({ route }: ChatScreenProps) => { ); }; -const styles = StyleSheet.create({ - header: { - padding: 10, - flexDirection: 'row', - backgroundColor: colorPallet.dark.static_black, - }, - headerText: { flex: 1, color: colorPallet.dark.static_white }, - notedButton: { - backgroundColor: colorPallet.light.primary, - justifyContent: 'center', - padding: 10, - borderRadius: 10, - marginLeft: 10, - }, - notedButtonText: { - color: colorPallet.dark.static_white, - fontWeight: '500', - }, -}); +const useStyles = () => { + const { theme } = useTheme(); + return useMemo( + () => + StyleSheet.create({ + header: { + padding: 10, + flexDirection: 'row', + backgroundColor: theme.colors.base5, + }, + headerText: { flex: 1, color: theme.colors.base1 }, + notedButton: { + backgroundColor: theme.colors.primary, + justifyContent: 'center', + padding: 10, + borderRadius: 10, + marginLeft: 10, + }, + notedButtonText: { + color: theme.colors.base1, + fontWeight: '500', + }, + }), + [theme], + ); +}; diff --git a/sample-apps/react-native/dogfood/src/theme.ts b/sample-apps/react-native/dogfood/src/theme.ts index 372e7f67ce..c1621e8d93 100644 --- a/sample-apps/react-native/dogfood/src/theme.ts +++ b/sample-apps/react-native/dogfood/src/theme.ts @@ -4,6 +4,7 @@ const opacityToHex = (opacity: number) => { .padStart(2, '0'); }; +// TODO add type Theme to this object export const appTheme = { colors: { static_grey: '#272A30', From 00a6373e98f4f23053611f00cd7445d10d03e8e6 Mon Sep 17 00:00:00 2001 From: Kristian Date: Wed, 16 Oct 2024 12:10:35 +0200 Subject: [PATCH 02/35] feat(design-v2): Call control buttons (#1514) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## ๐ŸŽฏ Goal - Jira Ticket: [PBE-5857](https://stream-io.atlassian.net/browse/PBE-5857) - Add new call control buttons ## ๐Ÿ›  Implementation details โœ… ParticipantInfo button is moved to the bottom call controls sections โœ… Around half of the call control buttons in the bottom section are moved to bottom drawer and the remaining main buttons are split in left and right sections โœ… Add more button is added that will open bottom drawer with more call controls โœ… New styling and icons is applied on the call controls ## ๐ŸŽจ UI Changes iOS
Before After
ios-after ios-after
Android
Before After
ios-after ios-after
[PBE-5857]: https://stream-io.atlassian.net/browse/PBE-5857?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ --- .../components/CallControls.test.tsx | 47 +------ .../components/ParticipantView.test.tsx | 1 - .../04-ui-components/call/call-content.mdx | 1 - .../04-ui-components/call/call-top-view.mdx | 4 - .../call-content/participants-info-badge.mdx | 5 - .../Call/CallContent/CallContent.tsx | 24 +--- .../Call/CallControls/CallControlsButton.tsx | 20 +-- .../Call/CallControls/ChatButton.tsx | 90 ------------- .../CallControls/ToggleAudioPreviewButton.tsx | 26 ++-- .../ToggleAudioPublishingButton.tsx | 25 ++-- .../CallControls/ToggleVideoPreviewButton.tsx | 29 +++-- .../ToggleVideoPublishingButton.tsx | 25 ++-- .../components/Call/CallControls/index.tsx | 1 - .../Call/CallTopView/CallTopView.tsx | 22 ---- .../CallTopView/ParticipantsInfoBadge.tsx | 119 ------------------ .../src/components/Call/CallTopView/index.ts | 1 - .../src/components/Call/Lobby/Lobby.tsx | 24 +--- .../LivestreamAudioControlButton.tsx | 5 +- .../LivestreamVideoControlButton.tsx | 5 +- .../FloatingParticipantView/index.tsx | 3 +- .../ParticipantView/ParticipantLabel.tsx | 40 +----- .../react-native-sdk/src/constants/TestIds.ts | 1 + .../src/icons/IconWrapper.tsx | 15 +++ packages/react-native-sdk/src/icons/Mic.tsx | 11 +- .../react-native-sdk/src/icons/MicOff.tsx | 7 +- .../src/icons/Participants.tsx | 18 --- packages/react-native-sdk/src/icons/Video.tsx | 7 +- .../react-native-sdk/src/icons/VideoSlash.tsx | 12 +- packages/react-native-sdk/src/icons/index.tsx | 3 +- packages/react-native-sdk/src/theme/colors.ts | 12 +- packages/react-native-sdk/src/theme/theme.ts | 27 +++- packages/react-native-sdk/src/theme/types.ts | 7 ++ .../react-native/dogfood/ios/Podfile.lock | 4 +- .../react-native/dogfood/src/assets/Audio.tsx | 19 +++ .../react-native/dogfood/src/assets/Chat.tsx | 9 +- .../dogfood/src/assets/LiveStreamChat.tsx | 2 +- .../dogfood/src/assets/MoreActions.tsx | 19 +++ .../dogfood/src/assets/Participants.tsx | 19 +++ .../dogfood/src/assets/RecordCall.tsx | 23 ++++ .../dogfood/src/components/ActiveCall.tsx | 93 ++++++++------ .../components/CallControlls/AudioButton.tsx | 49 ++++++++ .../CallControlls/BadgeCountIndicator.tsx | 68 ++++++++++ .../CallControlls/CallControlsComponent.tsx | 95 ++++++++++++++ .../components/CallControlls/ChatButton.tsx | 45 +++++++ .../CallControlls/MoreActionsButton.tsx | 56 +++++++++ .../CallControlls/ParticipantsButton.tsx | 68 ++++++++++ .../CallControlls/RecordCallButton.tsx | 54 ++++++++ .../src/components/CallControlsComponent.tsx | 84 ------------- .../LiveStreamChatControlButton.tsx | 4 +- .../dogfood/src/components/MeetingUI.tsx | 1 - .../dogfood/src/components/VideoWrapper.tsx | 8 +- sample-apps/react-native/dogfood/src/theme.ts | 17 +++ 52 files changed, 778 insertions(+), 596 deletions(-) delete mode 100644 packages/react-native-sdk/docusaurus/docs/reactnative/common-content/ui-components/call/call-content/participants-info-badge.mdx delete mode 100644 packages/react-native-sdk/src/components/Call/CallControls/ChatButton.tsx delete mode 100644 packages/react-native-sdk/src/components/Call/CallTopView/ParticipantsInfoBadge.tsx create mode 100644 packages/react-native-sdk/src/icons/IconWrapper.tsx delete mode 100644 packages/react-native-sdk/src/icons/Participants.tsx create mode 100644 sample-apps/react-native/dogfood/src/assets/Audio.tsx rename packages/react-native-sdk/src/icons/Chat.tsx => sample-apps/react-native/dogfood/src/assets/LiveStreamChat.tsx (91%) create mode 100644 sample-apps/react-native/dogfood/src/assets/MoreActions.tsx create mode 100644 sample-apps/react-native/dogfood/src/assets/Participants.tsx create mode 100644 sample-apps/react-native/dogfood/src/assets/RecordCall.tsx create mode 100644 sample-apps/react-native/dogfood/src/components/CallControlls/AudioButton.tsx create mode 100644 sample-apps/react-native/dogfood/src/components/CallControlls/BadgeCountIndicator.tsx create mode 100644 sample-apps/react-native/dogfood/src/components/CallControlls/CallControlsComponent.tsx create mode 100644 sample-apps/react-native/dogfood/src/components/CallControlls/ChatButton.tsx create mode 100644 sample-apps/react-native/dogfood/src/components/CallControlls/MoreActionsButton.tsx create mode 100644 sample-apps/react-native/dogfood/src/components/CallControlls/ParticipantsButton.tsx create mode 100644 sample-apps/react-native/dogfood/src/components/CallControlls/RecordCallButton.tsx delete mode 100644 sample-apps/react-native/dogfood/src/components/CallControlsComponent.tsx diff --git a/packages/react-native-sdk/__tests__/components/CallControls.test.tsx b/packages/react-native-sdk/__tests__/components/CallControls.test.tsx index 49188e04b4..2b611fc123 100644 --- a/packages/react-native-sdk/__tests__/components/CallControls.test.tsx +++ b/packages/react-native-sdk/__tests__/components/CallControls.test.tsx @@ -3,11 +3,10 @@ import { mockClientWithUser } from '../mocks/client'; import mockParticipant from '../mocks/participant'; import { ButtonTestIds, ComponentTestIds } from '../../src/constants/TestIds'; import { mockCall } from '../mocks/call'; -import { fireEvent, render, screen, waitFor } from '../utils/RNTLTools'; +import { fireEvent, render, screen } from '../utils/RNTLTools'; import { OwnCapability } from '@stream-io/video-client'; import { defaultEmojiReactions } from '../../src/constants'; -import { CallControls } from '../../src/components/Call/CallControls/CallControls'; -import { ChatButton } from '../../src/components/Call/CallControls/ChatButton'; +import { CallControls } from '../../src'; import { HangUpCallButton } from '../../src/components/Call/CallControls/HangupCallButton'; import { ReactionsButton } from '../../src/components/Call/CallControls/ReactionsButton'; @@ -18,48 +17,6 @@ enum P_IDS { LOCAL_1 = 'local-1', } -describe('ChatButton', () => { - it('should render an unread badge indicator when the value is defined in the chatButton prop', async () => { - const call = mockCall(mockClientWithUser(), [ - mockParticipant({ - isLocalParticipant: true, - sessionId: P_IDS.LOCAL_1, - userId: P_IDS.LOCAL_1, - }), - ]); - - render(, { - call, - }); - - const indicator = await screen.findByText('1'); - - expect(indicator).toBeVisible(); - }); - - it('should not render an unread badge indicator when the value is 0 in the chatButton prop', async () => { - const call = mockCall(mockClientWithUser(), [ - mockParticipant({ - isLocalParticipant: true, - sessionId: P_IDS.LOCAL_1, - userId: P_IDS.LOCAL_1, - }), - ]); - - render(, { - call, - }); - - await waitFor(() => - expect(() => - screen.getByTestId(ComponentTestIds.CHAT_UNREAD_BADGE_COUNT_INDICATOR) - ).toThrow( - /Unable to find an element with testID: chat-unread-badge-count-indicator/i - ) - ); - }); -}); - describe('ReactionsButton', () => { it('render reaction button in call controls component', async () => { const call = mockCall( diff --git a/packages/react-native-sdk/__tests__/components/ParticipantView.test.tsx b/packages/react-native-sdk/__tests__/components/ParticipantView.test.tsx index 15077486ba..c604478f83 100644 --- a/packages/react-native-sdk/__tests__/components/ParticipantView.test.tsx +++ b/packages/react-native-sdk/__tests__/components/ParticipantView.test.tsx @@ -43,7 +43,6 @@ describe('ParticipantView', () => { expect( await screen.findByTestId(ComponentTestIds.PARTICIPANT_AVATAR) ).toBeOnTheScreen(); - expect(screen.getByTestId(IconTestIds.MUTED_VIDEO)).toBeOnTheScreen(); expect(screen.getByText(testParticipant.name)).toBeOnTheScreen(); // reaction is visible and then disappears after 5500 ms expect(screen.getByText('๐ŸŽ‰')).toBeOnTheScreen(); diff --git a/packages/react-native-sdk/docusaurus/docs/reactnative/04-ui-components/call/call-content.mdx b/packages/react-native-sdk/docusaurus/docs/reactnative/04-ui-components/call/call-content.mdx index bf561290fd..63086107a8 100644 --- a/packages/react-native-sdk/docusaurus/docs/reactnative/04-ui-components/call/call-content.mdx +++ b/packages/react-native-sdk/docusaurus/docs/reactnative/04-ui-components/call/call-content.mdx @@ -10,7 +10,6 @@ import CallContentSpotlight from '../../assets/04-ui-components/call/call-conten import CallTopView from '../../common-content/ui-components/call/call-content/call-top-view.mdx'; import CallControls from '../../common-content/ui-components/call/call-content/call-controls.mdx'; -import ParticipantsInfoBadge from '../../common-content/ui-components/call/call-content/participants-info-badge.mdx'; import Landscape from '../../common-content/ui-components/call/call-content/landscape.mdx'; import OnBackPressed from '../../common-content/ui-components/call/call-content/on-back-pressed.mdx'; import OnParticipantInfoPress from '../../common-content/ui-components/call/call-content/on-participant-info-press.mdx'; diff --git a/packages/react-native-sdk/docusaurus/docs/reactnative/04-ui-components/call/call-top-view.mdx b/packages/react-native-sdk/docusaurus/docs/reactnative/04-ui-components/call/call-top-view.mdx index 6f82a92401..27f7aad3ce 100644 --- a/packages/react-native-sdk/docusaurus/docs/reactnative/04-ui-components/call/call-top-view.mdx +++ b/packages/react-native-sdk/docusaurus/docs/reactnative/04-ui-components/call/call-top-view.mdx @@ -60,10 +60,6 @@ Style to override the container of the `CallTopView`. | ---------------------------------------------------------- | | [ViewStyle](https://reactnative.dev/docs/view-style-props) | -### `ParticipantsInfoBadge` - - - ## Customization You can create your own custom `CallTopView` using the [Call Top View UI Cookbook guide](../../../ui-cookbook/replacing-call-top-view/). diff --git a/packages/react-native-sdk/docusaurus/docs/reactnative/common-content/ui-components/call/call-content/participants-info-badge.mdx b/packages/react-native-sdk/docusaurus/docs/reactnative/common-content/ui-components/call/call-content/participants-info-badge.mdx deleted file mode 100644 index 92a7cb3c9d..0000000000 --- a/packages/react-native-sdk/docusaurus/docs/reactnative/common-content/ui-components/call/call-content/participants-info-badge.mdx +++ /dev/null @@ -1,5 +0,0 @@ -Component to customize the ParticipantInfoBadge of the CallTopView. - -| Type | Default Value | -| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `ComponentType`\| `undefined` | [`ParticipantsInfoBadge`](https://github.com/GetStream/stream-video-js/blob/main/packages/react-native-sdk/src/components/Call/CallTopView/ParticipantsInfoBadge.tsx) | diff --git a/packages/react-native-sdk/src/components/Call/CallContent/CallContent.tsx b/packages/react-native-sdk/src/components/Call/CallContent/CallContent.tsx index 51637a173e..2539652703 100644 --- a/packages/react-native-sdk/src/components/Call/CallContent/CallContent.tsx +++ b/packages/react-native-sdk/src/components/Call/CallContent/CallContent.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useState } from 'react'; -import { StyleSheet, View, ViewStyle } from 'react-native'; +import { StyleSheet, View } from 'react-native'; import InCallManager from 'react-native-incall-manager'; import { @@ -71,10 +71,7 @@ export type CallContentProps = Pick< HangUpCallButtonProps, 'onHangupCallHandler' > & - Pick< - CallTopViewProps, - 'onBackPressed' | 'onParticipantInfoPress' | 'ParticipantsInfoBadge' - > & + Pick & CallContentComponentProps & { /** * This switches the participant's layout between the grid and the spotlight mode. @@ -101,7 +98,6 @@ export type CallContentProps = Pick< export const CallContent = ({ onBackPressed, - onParticipantInfoPress, onHangupCallHandler, CallParticipantsList, CallTopView = DefaultCallTopView, @@ -113,7 +109,6 @@ export const CallContent = ({ ParticipantReaction, ParticipantVideoFallback, ParticipantView, - ParticipantsInfoBadge, VideoRenderer, layout = 'grid', landscape = false, @@ -201,10 +196,6 @@ export const CallContent = ({ supportedReactions, }; - const landscapeStyles: ViewStyle = { - flexDirection: landscape ? 'row' : 'column', - }; - return ( <> {!disablePictureInPicture && ( @@ -212,8 +203,8 @@ export const CallContent = ({ includeLocalParticipantVideo={iOSPiPIncludeLocalParticipantVideo} /> )} - - + + {!isInPiPMode && CallTopView && ( - + )} {showFloatingView && FloatingParticipantView && ( [ styles.container, { - backgroundColor: disabled ? colors.disabled : colorProp || colors.base1, + backgroundColor: disabled + ? colors.buttonPrimaryDisabled + : colorProp || colors.buttonSecondaryDefault, opacity: pressed ? 0.2 : 1, - height: size || buttonSizes.sm, - width: size || buttonSizes.sm, - borderRadius: (size || buttonSizes.sm) / 2, - borderColor: colors.background1, + height: size || roundButtonSizes.lg, + width: size || roundButtonSizes.lg, + borderRadius: defaults.borderRadius, }, styleProp?.container ?? null, container, ]; + const childrenSize = (size || roundButtonSizes.lg) / 2 - 5; return ( diff --git a/packages/react-native-sdk/src/components/Call/CallControls/ChatButton.tsx b/packages/react-native-sdk/src/components/Call/CallControls/ChatButton.tsx deleted file mode 100644 index 66a0bda86c..0000000000 --- a/packages/react-native-sdk/src/components/Call/CallControls/ChatButton.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import React from 'react'; -import { StyleSheet, Text, View } from 'react-native'; -import { CallControlsButton } from './CallControlsButton'; -import { Chat } from '../../../icons'; -import { ComponentTestIds } from '../../../constants/TestIds'; -import { Z_INDEX } from '../../../constants'; -import { useTheme } from '../../../contexts/ThemeContext'; - -/** - * The props for the Chat Button in the Call Controls. - */ -export type ChatButtonProps = { - /** - * Handler to be called when the chat button is pressed. - * @returns void - */ - onPressHandler?: () => void; - /** - * The count of the current unread message to be displayed above on the Chat button. - */ - unreadBadgeCount?: number; -}; - -/** - * Button to open the Chat window while in the call. - * - * This call also display the unread count indicator/badge is there messages that are unread. - */ -export const ChatButton = ({ - onPressHandler, - unreadBadgeCount, -}: ChatButtonProps) => { - const { - theme: { colors, chatButton }, - } = useTheme(); - return ( - - - - - ); -}; - -const UnreadBadgeCountIndicator = ({ - count, -}: { - count: ChatButtonProps['unreadBadgeCount']; -}) => { - const { - theme: { colors, typefaces }, - } = useTheme(); - - // Don't show badge if count is 0 or undefined - if (!count) { - return null; - } - - return ( - - - {count} - - - ); -}; - -const styles = StyleSheet.create({ - chatBadge: { - borderRadius: 30, - position: 'absolute', - left: 15, - bottom: 20, - zIndex: Z_INDEX.IN_FRONT, - height: 24, - width: 24, - justifyContent: 'center', - }, - chatBadgeText: { - textAlign: 'center', - }, -}); diff --git a/packages/react-native-sdk/src/components/Call/CallControls/ToggleAudioPreviewButton.tsx b/packages/react-native-sdk/src/components/Call/CallControls/ToggleAudioPreviewButton.tsx index 3a30741189..faeefc5478 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/ToggleAudioPreviewButton.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/ToggleAudioPreviewButton.tsx @@ -1,7 +1,7 @@ import { useCallStateHooks } from '@stream-io/video-react-bindings'; import React from 'react'; import { useTheme } from '../../../contexts'; -import { Mic, MicOff } from '../../../icons'; +import { IconWrapper, Mic, MicOff } from '../../../icons'; import { CallControlsButton } from './CallControlsButton'; /** @@ -26,6 +26,7 @@ export const ToggleAudioPreviewButton = ({ colors, toggleAudioPreviewButton, variants: { buttonSizes }, + defaults, }, } = useTheme(); const { useMicrophoneState } = useCallStateHooks(); @@ -42,21 +43,24 @@ export const ToggleAudioPreviewButton = ({ return ( - {!optimisticIsMute ? ( - - ) : ( - - )} + + {!optimisticIsMute ? ( + + ) : ( + + )} + ); }; diff --git a/packages/react-native-sdk/src/components/Call/CallControls/ToggleAudioPublishingButton.tsx b/packages/react-native-sdk/src/components/Call/CallControls/ToggleAudioPublishingButton.tsx index c0aed84ee3..1e8e8b45fc 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/ToggleAudioPublishingButton.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/ToggleAudioPublishingButton.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { OwnCapability } from '@stream-io/video-client'; import { Restricted, useCallStateHooks } from '@stream-io/video-react-bindings'; import { CallControlsButton } from './CallControlsButton'; -import { Mic, MicOff } from '../../../icons'; +import { IconWrapper, Mic, MicOff } from '../../../icons'; import { useTheme } from '../../../contexts/ThemeContext'; /** @@ -26,7 +26,7 @@ export const ToggleAudioPublishingButton = ({ const { optimisticIsMute, microphone } = useMicrophoneState(); const { - theme: { colors, toggleAudioPublishingButton }, + theme: { colors, toggleAudioPublishingButton, defaults }, } = useTheme(); const onPress = async () => { if (onPressHandler) { @@ -41,14 +41,23 @@ export const ToggleAudioPublishingButton = ({ - {!optimisticIsMute ? ( - - ) : ( - - )} + + {!optimisticIsMute ? ( + + ) : ( + + )} + ); diff --git a/packages/react-native-sdk/src/components/Call/CallControls/ToggleVideoPreviewButton.tsx b/packages/react-native-sdk/src/components/Call/CallControls/ToggleVideoPreviewButton.tsx index f3da81b65e..6b772dd8d4 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/ToggleVideoPreviewButton.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/ToggleVideoPreviewButton.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { useCallStateHooks } from '@stream-io/video-react-bindings'; import { useTheme } from '../../../contexts'; import { CallControlsButton } from './CallControlsButton'; -import { Video, VideoSlash } from '../../../icons'; +import { IconWrapper, Video, VideoSlash } from '../../../icons'; /** * Props for the Toggle Video preview button @@ -26,6 +26,7 @@ export const ToggleVideoPreviewButton = ({ colors, toggleVideoPreviewButton, variants: { buttonSizes }, + defaults, }, } = useTheme(); const { useCameraState, useCallSettings } = useCallStateHooks(); @@ -47,21 +48,27 @@ export const ToggleVideoPreviewButton = ({ return ( - {!optimisticIsMute ? ( - ); }; diff --git a/packages/react-native-sdk/src/components/Call/CallControls/ToggleVideoPublishingButton.tsx b/packages/react-native-sdk/src/components/Call/CallControls/ToggleVideoPublishingButton.tsx index a2441a0ce3..ecab938bbb 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/ToggleVideoPublishingButton.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/ToggleVideoPublishingButton.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { OwnCapability } from '@stream-io/video-client'; import { Restricted, useCallStateHooks } from '@stream-io/video-react-bindings'; import { CallControlsButton } from './CallControlsButton'; -import { Video, VideoSlash } from '../../../icons'; +import { IconWrapper, Video, VideoSlash } from '../../../icons'; import { useTheme } from '../../../contexts/ThemeContext'; /** @@ -27,7 +27,7 @@ export const ToggleVideoPublishingButton = ({ const callSettings = useCallSettings(); const isVideoEnabledInCall = callSettings?.video.enabled; const { - theme: { colors }, + theme: { colors, defaults }, } = useTheme(); const onPress = async () => { if (onPressHandler) { @@ -45,13 +45,22 @@ export const ToggleVideoPublishingButton = ({ - {!optimisticIsMute ? ( - ); diff --git a/packages/react-native-sdk/src/components/Call/CallControls/index.tsx b/packages/react-native-sdk/src/components/Call/CallControls/index.tsx index 1e1d5b50de..1fa2a0543c 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/index.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/index.tsx @@ -6,7 +6,6 @@ export * from './ToggleVideoPreviewButton'; export * from './ToggleAudioPublishingButton'; export * from './ToggleVideoPublishingButton'; export * from './ToggleCameraFaceButton'; -export * from './ChatButton'; export * from './ReactionsButton'; export * from './CallControls'; export * from './CallControlsButton'; diff --git a/packages/react-native-sdk/src/components/Call/CallTopView/CallTopView.tsx b/packages/react-native-sdk/src/components/Call/CallTopView/CallTopView.tsx index 19b4993d86..e16fed2516 100644 --- a/packages/react-native-sdk/src/components/Call/CallTopView/CallTopView.tsx +++ b/packages/react-native-sdk/src/components/Call/CallTopView/CallTopView.tsx @@ -7,10 +7,6 @@ import { StyleProp, ViewStyle, } from 'react-native'; -import { - ParticipantsInfoBadge as DefaultParticipantsInfoBadge, - ParticipantsInfoBadgeProps, -} from './ParticipantsInfoBadge'; import { Back } from '../../../icons/Back'; import { TopViewBackground } from '../../../icons'; import { useCallStateHooks, useI18n } from '@stream-io/video-react-bindings'; @@ -23,11 +19,6 @@ export type CallTopViewProps = { * @returns void */ onBackPressed?: () => void; - /** - * Handler to be called when the Participant icon is pressed in the CallTopView. - * @returns - */ - onParticipantInfoPress?: () => void; /** * Title to be rendered at the center of the Header. */ @@ -36,18 +27,12 @@ export type CallTopViewProps = { * Style to override the container of the CallTopView. */ style?: StyleProp; - /** - * Component to customize the ParticipantInfoBadge of the CallTopView. - */ - ParticipantsInfoBadge?: React.ComponentType | null; }; export const CallTopView = ({ onBackPressed, - onParticipantInfoPress, title, style: styleProp, - ParticipantsInfoBadge = DefaultParticipantsInfoBadge, }: CallTopViewProps) => { const [callTopViewHeight, setCallTopViewHeight] = useState(0); const [callTopViewWidth, setCallTopViewWidth] = useState(0); @@ -121,13 +106,6 @@ export const CallTopView = ({ ) )} - - {ParticipantsInfoBadge && ( - - )} - ); diff --git a/packages/react-native-sdk/src/components/Call/CallTopView/ParticipantsInfoBadge.tsx b/packages/react-native-sdk/src/components/Call/CallTopView/ParticipantsInfoBadge.tsx deleted file mode 100644 index 15d24f6ea2..0000000000 --- a/packages/react-native-sdk/src/components/Call/CallTopView/ParticipantsInfoBadge.tsx +++ /dev/null @@ -1,119 +0,0 @@ -import React from 'react'; -import { Pressable, StyleSheet, Text, View } from 'react-native'; -import { Participants } from '../../../icons'; -import { useCallStateHooks } from '@stream-io/video-react-bindings'; -import { Z_INDEX } from '../../../constants'; -import { CallTopViewProps } from '..'; -import { ButtonTestIds } from '../../../constants/TestIds'; -import { useTheme } from '../../../contexts/ThemeContext'; -import { CallingState } from '@stream-io/video-client'; - -/** - * Props for the ParticipantsInfoBadge component. - */ -export type ParticipantsInfoBadgeProps = Pick< - CallTopViewProps, - 'onParticipantInfoPress' ->; - -/** - * Badge that shows the number of participants in the call. - * When pressed, it opens the ParticipantsInfoList. - */ -export const ParticipantsInfoBadge = ({ - onParticipantInfoPress, -}: ParticipantsInfoBadgeProps) => { - const { - theme: { - colors, - participantInfoBadge, - typefaces, - variants: { iconSizes }, - }, - } = useTheme(); - const { useParticipantCount, useCallMembers, useCallCallingState } = - useCallStateHooks(); - const participantCount = useParticipantCount(); - const members = useCallMembers(); - const callingState = useCallCallingState(); - - let count = 0; - /** - * We show member's length if Incoming and Outgoing Call Views are rendered. - * Else we show the count of the participants that are in the call. - * Since the members count also includes caller/callee, we reduce the count by 1. - **/ - if (callingState === CallingState.RINGING) { - count = members.length - 1; - } else { - count = participantCount; - } - - if (count === 0) { - return null; - } - - return ( - [ - styles.container, - { opacity: pressed ? 0.2 : 1 }, - participantInfoBadge.container, - ]} - disabled={!onParticipantInfoPress} - testID={ButtonTestIds.PARTICIPANTS_INFO} - > - - - - - - {count} - - - - ); -}; - -const styles = StyleSheet.create({ - container: { - flexDirection: 'row', - }, - participantCountContainer: { - justifyContent: 'center', - paddingHorizontal: 8, - borderRadius: 30, - zIndex: Z_INDEX.IN_FRONT, - bottom: 12, - right: 12, - }, - participantCountText: { - includeFontPadding: false, - textAlign: 'center', - }, -}); diff --git a/packages/react-native-sdk/src/components/Call/CallTopView/index.ts b/packages/react-native-sdk/src/components/Call/CallTopView/index.ts index 7734edc003..bb5d521f5b 100644 --- a/packages/react-native-sdk/src/components/Call/CallTopView/index.ts +++ b/packages/react-native-sdk/src/components/Call/CallTopView/index.ts @@ -1,2 +1 @@ export * from './CallTopView'; -export * from './ParticipantsInfoBadge'; diff --git a/packages/react-native-sdk/src/components/Call/Lobby/Lobby.tsx b/packages/react-native-sdk/src/components/Call/Lobby/Lobby.tsx index 4ebbbbba8e..23db831fba 100644 --- a/packages/react-native-sdk/src/components/Call/Lobby/Lobby.tsx +++ b/packages/react-native-sdk/src/components/Call/Lobby/Lobby.tsx @@ -1,6 +1,5 @@ import React, { ComponentType } from 'react'; import { StyleSheet, Text, View, ViewStyle } from 'react-native'; -import { MicOff } from '../../../icons'; import { useCallStateHooks, useConnectedUser, @@ -158,17 +157,10 @@ export const Lobby = ({ const ParticipantStatus = () => { const { - theme: { - colors, - typefaces, - lobby, - variants: { iconSizes }, - }, + theme: { colors, typefaces, lobby }, } = useTheme(); const connectedUser = useConnectedUser(); - const { useMicrophoneState } = useCallStateHooks(); const participantLabel = connectedUser?.name ?? connectedUser?.id; - const { status: micStatus } = useMicrophoneState(); return ( { > {participantLabel}
- {(!micStatus || micStatus === 'disabled') && ( - - - - )}
); }; diff --git a/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamAudioControlButton.tsx b/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamAudioControlButton.tsx index 2fb2defaed..005d542298 100644 --- a/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamAudioControlButton.tsx +++ b/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamAudioControlButton.tsx @@ -15,6 +15,7 @@ export const LivestreamAudioControlButton = () => { colors, variants: { iconSizes, buttonSizes }, livestreamAudioControlButton, + defaults, }, } = useTheme(); @@ -46,9 +47,9 @@ export const LivestreamAudioControlButton = () => { ]} > {!optimisticIsMute ? ( - + ) : ( - + )}
diff --git a/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamVideoControlButton.tsx b/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamVideoControlButton.tsx index 1f47b71be5..e73f6c7a84 100644 --- a/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamVideoControlButton.tsx +++ b/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamVideoControlButton.tsx @@ -17,6 +17,7 @@ export const LivestreamVideoControlButton = () => { colors, variants: { iconSizes, buttonSizes }, livestreamVideoControlButton, + defaults, }, } = useTheme(); @@ -52,9 +53,9 @@ export const LivestreamVideoControlButton = () => { ]} > {!optimisticIsMute ? ( -
- {isAudioMuted && ( - - - - )} - {isVideoMuted && ( - - - - )} {isPinningEnabled && ( { + return {children}; +}; + +const styles = StyleSheet.create({ + container: { + justifyContent: 'center', + alignItems: 'center', + flex: 1, + }, +}); diff --git a/packages/react-native-sdk/src/icons/Mic.tsx b/packages/react-native-sdk/src/icons/Mic.tsx index 229c63f7dc..e46bd03c20 100644 --- a/packages/react-native-sdk/src/icons/Mic.tsx +++ b/packages/react-native-sdk/src/icons/Mic.tsx @@ -4,16 +4,13 @@ import { ColorValue } from 'react-native/types'; type Props = { color: ColorValue; + size: number; }; -export const Mic = ({ color }: Props) => ( - +export const Mic = ({ color, size }: Props) => ( + - diff --git a/packages/react-native-sdk/src/icons/MicOff.tsx b/packages/react-native-sdk/src/icons/MicOff.tsx index 405bc1c4ee..da7510a9ba 100644 --- a/packages/react-native-sdk/src/icons/MicOff.tsx +++ b/packages/react-native-sdk/src/icons/MicOff.tsx @@ -4,12 +4,13 @@ import { ColorValue } from 'react-native/types'; type Props = { color: ColorValue; + size: number; }; -export const MicOff = ({ color }: Props) => ( - +export const MicOff = ({ color, size }: Props) => ( + diff --git a/packages/react-native-sdk/src/icons/Participants.tsx b/packages/react-native-sdk/src/icons/Participants.tsx deleted file mode 100644 index 82be4a3fe5..0000000000 --- a/packages/react-native-sdk/src/icons/Participants.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import React from 'react'; -import { Svg, Path } from 'react-native-svg'; -import { ColorValue } from 'react-native/types'; - -type Props = { - color: ColorValue; -}; - -export const Participants = ({ color }: Props) => ( - - - -); diff --git a/packages/react-native-sdk/src/icons/Video.tsx b/packages/react-native-sdk/src/icons/Video.tsx index 331cae6d32..62471ca577 100644 --- a/packages/react-native-sdk/src/icons/Video.tsx +++ b/packages/react-native-sdk/src/icons/Video.tsx @@ -4,12 +4,13 @@ import { ColorValue } from 'react-native/types'; type Props = { color: ColorValue; + size: number; }; -export const Video = ({ color }: Props) => ( - +export const Video = ({ color, size }: Props) => ( + diff --git a/packages/react-native-sdk/src/icons/VideoSlash.tsx b/packages/react-native-sdk/src/icons/VideoSlash.tsx index 6f583561e4..84f02035fd 100644 --- a/packages/react-native-sdk/src/icons/VideoSlash.tsx +++ b/packages/react-native-sdk/src/icons/VideoSlash.tsx @@ -5,12 +5,18 @@ import { IconTestIds } from '../constants/TestIds'; type Props = { color: ColorValue; + size: number; }; -export const VideoSlash = ({ color }: Props) => ( - +export const VideoSlash = ({ color, size }: Props) => ( + diff --git a/packages/react-native-sdk/src/icons/index.tsx b/packages/react-native-sdk/src/icons/index.tsx index 814d18d34d..f3b3ee722f 100644 --- a/packages/react-native-sdk/src/icons/index.tsx +++ b/packages/react-native-sdk/src/icons/index.tsx @@ -6,8 +6,6 @@ export * from './PhoneDown'; export * from './Settings'; export * from './Video'; export * from './VideoSlash'; -export * from './Chat'; -export * from './Participants'; export * from './ThreeDots'; export * from './PinVertical'; export * from './Spotlight'; @@ -21,3 +19,4 @@ export * from './StartStreamIcon'; export * from './StopScreenShare'; export * from './EndStreamIcon'; export * from './LeaveStreamIcon'; +export * from './IconWrapper'; diff --git a/packages/react-native-sdk/src/theme/colors.ts b/packages/react-native-sdk/src/theme/colors.ts index 1d09982558..39c3beb0d3 100644 --- a/packages/react-native-sdk/src/theme/colors.ts +++ b/packages/react-native-sdk/src/theme/colors.ts @@ -28,7 +28,14 @@ const colors: ColorScheme = { background5: palette.grey900, background6: palette.grey950 + opacityToHex(0.85), + // Colors candidates for the default theme buttonPrimaryDefault: '#005fff', + buttonSecondaryDefault: '#19232d', + buttonSecondaryWarningDefault: '#dc433b', + iconPrimaryDefault: '#eff0f1', + iconAlertSuccess: '#00e2a1', + sheetPrimary: '#000000', + buttonPrimaryDisabled: '#1b2c43', buttonPrimaryHover: '#4c8fff', buttonPrimaryPressed: '#123d82', @@ -37,14 +44,12 @@ const colors: ColorScheme = { buttonQuaternaryDisabled: '#31292f', buttonQuaternaryHover: '#e77b76', buttonQuaternaryPressed: '#7d3535', - buttonSecondaryDefault: '#19232d', buttonSecondaryDisabled: '#1e262e29', buttonSecondaryHover: '#323b44', buttonSecondaryPressed: '#101213', buttonSecondaryActiveDefault: '#005fff', buttonSecondaryActiveHover: '#4c8fff', buttonSecondaryActivePressed: '#123d82', - buttonSecondaryWarningDefault: '#dc433b', buttonSecondaryWarningHover: '#e77b76', buttonSecondaryWarningPressed: '#7d3535', buttonTertiaryActive: '#19232d', @@ -60,16 +65,13 @@ const colors: ColorScheme = { containerTertiary: '#2d3042', containerWarning: '#31292f', iconAlertCaution: '#ffd646', - iconAlertSuccess: '#00e2a1', iconAlertWarning: '#dc433b', iconPrimaryAccent: '#005fff', - iconPrimaryDefault: '#eff0f1', iconPrimaryDisabled: '#7e8389', iconPrimaryHover: '#e3e4e5', iconPrimaryOnAccent: '#eff0f1', iconPrimaryPressed: '#656b72', sheetOverlay: '#0c0d0ea6', - sheetPrimary: '#000000', sheetSecondary: '#101213', sheetTertiary: '#19232d', typeAccent: '#00e2a1', diff --git a/packages/react-native-sdk/src/theme/theme.ts b/packages/react-native-sdk/src/theme/theme.ts index 488257cb48..5b7eead4f3 100644 --- a/packages/react-native-sdk/src/theme/theme.ts +++ b/packages/react-native-sdk/src/theme/theme.ts @@ -1,15 +1,23 @@ import { ImageStyle, TextStyle, ViewStyle } from 'react-native/types'; import { colors } from './colors'; -import { ColorScheme, DimensionType, FontStyle, FontTypes } from './types'; +import { + ColorScheme, + DimensionType, + FontStyle, + FontTypes, + Insets, +} from './types'; import { ColorValue } from 'react-native'; export type Theme = { variants: { buttonSizes: DimensionType; + roundButtonSizes: DimensionType; iconSizes: DimensionType; avatarSizes: DimensionType; fontSizes: DimensionType; spacingSizes: DimensionType; + insets: Insets; }; typefaces: Record; defaults: { @@ -18,6 +26,7 @@ export type Theme = { margin: number; padding: number; fontSize: number; + iconSize: number; fontWeight: TextStyle['fontWeight']; borderRadius: ViewStyle['borderRadius']; borderColor: ColorValue; @@ -282,6 +291,13 @@ export type Theme = { export const defaultTheme: Theme = { variants: { + roundButtonSizes: { + xs: 16, + sm: 24, + md: 36, + lg: 44, + xl: 56, + }, buttonSizes: { xs: 40, sm: 50, @@ -317,6 +333,12 @@ export const defaultTheme: Theme = { lg: 20, xl: 24, }, + insets: { + top: 0, + right: 0, + bottom: 0, + left: 0, + }, }, typefaces: { heading4: { @@ -355,7 +377,8 @@ export const defaultTheme: Theme = { padding: 10, fontSize: 16, fontWeight: '500', - borderRadius: 10, + borderRadius: 32, + iconSize: 28, borderColor: colors.primary, borderWidth: 1, }, diff --git a/packages/react-native-sdk/src/theme/types.ts b/packages/react-native-sdk/src/theme/types.ts index d2ba8bf903..4c9c0db527 100644 --- a/packages/react-native-sdk/src/theme/types.ts +++ b/packages/react-native-sdk/src/theme/types.ts @@ -99,6 +99,13 @@ export type DimensionType = { xl: number; }; +export type Insets = { + top: number; + right: number; + bottom: number; + left: number; +}; + export type FontsScheme = Record; export type Theme = ColorType; diff --git a/sample-apps/react-native/dogfood/ios/Podfile.lock b/sample-apps/react-native/dogfood/ios/Podfile.lock index d95247de93..fa7ea9fdbd 100644 --- a/sample-apps/react-native/dogfood/ios/Podfile.lock +++ b/sample-apps/react-native/dogfood/ios/Podfile.lock @@ -1148,7 +1148,7 @@ PODS: - stream-react-native-webrtc (118.1.0): - JitsiWebRTC (~> 118.0.0) - React-Core - - stream-video-react-native (1.1.0): + - stream-video-react-native (1.1.1): - glog - RCT-Folly (= 2022.05.16.00) - React-Core @@ -1479,7 +1479,7 @@ SPEC CHECKSUMS: SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17 stream-io-video-filters-react-native: 8c345e6adf5164646696d45f9962c4199b2fe3b9 stream-react-native-webrtc: 4ccf61161f77c57b9aa45f78cb7f69b7d91f3e9f - stream-video-react-native: ffc867d9eb2a97f0eaa8b4376322ed6e82a5383d + stream-video-react-native: ff287d6bc897fffdf7b07ed3828e53bbf74bf576 TOCropViewController: 80b8985ad794298fb69d3341de183f33d1853654 Yoga: 1b901a6d6eeba4e8a2e8f308f708691cdb5db312 diff --git a/sample-apps/react-native/dogfood/src/assets/Audio.tsx b/sample-apps/react-native/dogfood/src/assets/Audio.tsx new file mode 100644 index 0000000000..ae5c26767f --- /dev/null +++ b/sample-apps/react-native/dogfood/src/assets/Audio.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { Svg, Path } from 'react-native-svg'; +import { ColorValue } from 'react-native/types'; + +type Props = { + color: ColorValue; + size: number; +}; + +const Audio = ({ color, size }: Props) => ( + + + +); + +export default Audio; diff --git a/sample-apps/react-native/dogfood/src/assets/Chat.tsx b/sample-apps/react-native/dogfood/src/assets/Chat.tsx index adc7b30f55..a6da4abe45 100644 --- a/sample-apps/react-native/dogfood/src/assets/Chat.tsx +++ b/sample-apps/react-native/dogfood/src/assets/Chat.tsx @@ -4,13 +4,16 @@ import { ColorValue } from 'react-native/types'; type Props = { color: ColorValue; + size: number; }; -export const Chat = ({ color }: Props) => ( - +const Chat = ({ color, size }: Props) => ( + ); + +export default Chat; diff --git a/packages/react-native-sdk/src/icons/Chat.tsx b/sample-apps/react-native/dogfood/src/assets/LiveStreamChat.tsx similarity index 91% rename from packages/react-native-sdk/src/icons/Chat.tsx rename to sample-apps/react-native/dogfood/src/assets/LiveStreamChat.tsx index adc7b30f55..2c7073acea 100644 --- a/packages/react-native-sdk/src/icons/Chat.tsx +++ b/sample-apps/react-native/dogfood/src/assets/LiveStreamChat.tsx @@ -6,7 +6,7 @@ type Props = { color: ColorValue; }; -export const Chat = ({ color }: Props) => ( +export const LiveStreamChat = ({ color }: Props) => ( ( + + + +); + +export default MoreActions; diff --git a/sample-apps/react-native/dogfood/src/assets/Participants.tsx b/sample-apps/react-native/dogfood/src/assets/Participants.tsx new file mode 100644 index 0000000000..02b95ca1c0 --- /dev/null +++ b/sample-apps/react-native/dogfood/src/assets/Participants.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { Svg, Path } from 'react-native-svg'; +import { ColorValue } from 'react-native/types'; + +type Props = { + color: ColorValue; + size: number; +}; + +const Participants = ({ color, size }: Props) => ( + + + +); + +export default Participants; diff --git a/sample-apps/react-native/dogfood/src/assets/RecordCall.tsx b/sample-apps/react-native/dogfood/src/assets/RecordCall.tsx new file mode 100644 index 0000000000..c07c995b43 --- /dev/null +++ b/sample-apps/react-native/dogfood/src/assets/RecordCall.tsx @@ -0,0 +1,23 @@ +import React from 'react'; +import { ColorValue } from 'react-native'; +import { Svg, Path } from 'react-native-svg'; + +type Props = { + color: ColorValue; + size: number; +}; + +const RecordCall = ({ color, size }: Props) => ( + + + + +); + +export default RecordCall; diff --git a/sample-apps/react-native/dogfood/src/components/ActiveCall.tsx b/sample-apps/react-native/dogfood/src/components/ActiveCall.tsx index 07ec207fbe..1f61e00fac 100644 --- a/sample-apps/react-native/dogfood/src/components/ActiveCall.tsx +++ b/sample-apps/react-native/dogfood/src/components/ActiveCall.tsx @@ -1,17 +1,18 @@ -import React, { useCallback, useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useState, useMemo } from 'react'; import { useCall, CallContent, - CallControlProps, + useTheme, } from '@stream-io/video-react-native-sdk'; -import { ActivityIndicator, StyleSheet } from 'react-native'; +import { ActivityIndicator, StyleSheet, View } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { ParticipantsInfoList } from './ParticipantsInfoList'; import { CallControlsComponent, CallControlsComponentProps, -} from './CallControlsComponent'; +} from './CallControlls/CallControlsComponent'; import { useOrientation } from '../hooks/useOrientation'; +import { Z_INDEX } from '../constants'; type ActiveCallProps = CallControlsComponentProps & { onBackPressed?: () => void; @@ -22,17 +23,17 @@ export const ActiveCall = ({ onChatOpenHandler, onBackPressed, onCallEnded, - onHangupCallHandler, unreadCountIndicator, }: ActiveCallProps) => { const [isCallParticipantsVisible, setIsCallParticipantsVisible] = useState(false); const call = useCall(); const currentOrientation = useOrientation(); + const styles = useStyles(); - const onOpenCallParticipantsInfo = () => { + const onOpenCallParticipantsInfo = useCallback(() => { setIsCallParticipantsVisible(true); - }; + }, []); useEffect(() => { return call?.on('call.ended', () => { @@ -40,42 +41,60 @@ export const ActiveCall = ({ }); }, [call, onCallEnded]); - const CustomControlsComponent = useCallback( - ({ landscape }: CallControlProps) => { - return ( - - ); - }, - [onChatOpenHandler, onHangupCallHandler, unreadCountIndicator], - ); + const CustomControlsComponent = useCallback(() => { + return ( + + ); + }, [onChatOpenHandler, onOpenCallParticipantsInfo, unreadCountIndicator]); if (!call) { return ; } return ( - - - - + + + + + + + ); }; -const styles = StyleSheet.create({ - container: { - flex: 1, - }, -}); +const useStyles = () => { + const { theme } = useTheme(); + + return useMemo( + () => + StyleSheet.create({ + container: { flex: 1 }, + callContent: { flex: 1 }, + safeArea: { flex: 1, paddingBottom: theme.variants.insets.bottom }, + unsafeArea: { + position: 'absolute', + left: 0, + right: 0, + bottom: 0, + height: theme.variants.insets.bottom, + backgroundColor: theme.colors.sheetPrimary, + }, + view: { + ...StyleSheet.absoluteFillObject, + zIndex: Z_INDEX.IN_FRONT, + }, + }), + [theme], + ); +}; diff --git a/sample-apps/react-native/dogfood/src/components/CallControlls/AudioButton.tsx b/sample-apps/react-native/dogfood/src/components/CallControlls/AudioButton.tsx new file mode 100644 index 0000000000..d53e4fbbfc --- /dev/null +++ b/sample-apps/react-native/dogfood/src/components/CallControlls/AudioButton.tsx @@ -0,0 +1,49 @@ +import React, { useState } from 'react'; +import { + CallControlsButton, + useTheme, +} from '@stream-io/video-react-native-sdk'; +import { IconWrapper } from '@stream-io/video-react-native-sdk/src/icons'; +import Audio from '../../assets/Audio'; + +/** + * The props for the Audio Button in the Call Controls. + */ +export type AudioButtonProps = { + /** + * Handler to be called when the audio button is pressed. + */ + onPressHandler?: () => void; +}; + +/** + * A button that can be used to switch audio output options + * like speaker, headphones, etc. + */ +export const AudioButton = ({ onPressHandler }: AudioButtonProps) => { + const { + theme: { colors, audioButton, variants }, + } = useTheme(); + + const [isPressed, setIsPressed] = useState(false); + const buttonColor = isPressed + ? colors.buttonPrimaryDefault + : colors.buttonSecondaryDefault; + + return ( + { + if (onPressHandler) { + onPressHandler(); + } + setIsPressed(!isPressed); + }} + style={audioButton} + color={buttonColor} + > + + + + + ); +}; diff --git a/sample-apps/react-native/dogfood/src/components/CallControlls/BadgeCountIndicator.tsx b/sample-apps/react-native/dogfood/src/components/CallControlls/BadgeCountIndicator.tsx new file mode 100644 index 0000000000..7b4323a2fc --- /dev/null +++ b/sample-apps/react-native/dogfood/src/components/CallControlls/BadgeCountIndicator.tsx @@ -0,0 +1,68 @@ +import React, { useMemo } from 'react'; +import { StyleSheet, Text, View } from 'react-native'; +import { useTheme } from '@stream-io/video-react-native-sdk'; +import { ComponentTestIds } from '@stream-io/video-react-native-sdk/src/constants/TestIds'; +import { Z_INDEX } from '../../constants'; + +/** + * A badge that displays a number. + * + * @prop {number} count - The number to display in the badge. + * + * @returns {ReactElement} A View with a Text that displays the count in the badge. + */ +export const BadgeCountIndicator = ({ + count, +}: { + count: number | undefined; +}) => { + const { + theme: { colors, typefaces }, + } = useTheme(); + const styles = useStyles(); + + // Don't show badge if count is 0 or undefined + if (!count) { + return null; + } + + return ( + + + {count} + + + ); +}; + +const useStyles = () => { + const { theme } = useTheme(); + return useMemo( + () => + StyleSheet.create({ + badge: { + position: 'absolute', + justifyContent: 'center', + borderRadius: theme.defaults.borderRadius, + left: 13, + bottom: 17, + zIndex: Z_INDEX.IN_FRONT, + height: theme.variants.roundButtonSizes.xs, + width: theme.variants.roundButtonSizes.xs, + }, + badgeText: { + textAlign: 'center', + }, + }), + [theme], + ); +}; diff --git a/sample-apps/react-native/dogfood/src/components/CallControlls/CallControlsComponent.tsx b/sample-apps/react-native/dogfood/src/components/CallControlls/CallControlsComponent.tsx new file mode 100644 index 0000000000..add4173789 --- /dev/null +++ b/sample-apps/react-native/dogfood/src/components/CallControlls/CallControlsComponent.tsx @@ -0,0 +1,95 @@ +import { + CallContentProps, + ToggleAudioPublishingButton, + ToggleVideoPublishingButton, + useCallStateHooks, +} from '@stream-io/video-react-native-sdk'; +import React from 'react'; +import { StyleSheet, Text, View } from 'react-native'; +import { appTheme } from '../../theme'; +import { Z_INDEX } from '../../constants'; +import { MoreActionsButton } from './MoreActionsButton'; +import { ParticipantsButton } from './ParticipantsButton'; +import { ChatButton } from './ChatButton'; +import { RecordCallButton } from './RecordCallButton'; +import { AudioButton } from './AudioButton'; + +export type CallControlsComponentProps = Pick< + CallContentProps, + 'supportedReactions' +> & { + onChatOpenHandler?: () => void; + onParticipantInfoPress?: () => void; + unreadCountIndicator?: number; +}; + +export const CallControlsComponent = ({ + onChatOpenHandler, + unreadCountIndicator, + onParticipantInfoPress, +}: CallControlsComponentProps) => { + const { useMicrophoneState } = useCallStateHooks(); + const { isSpeakingWhileMuted } = useMicrophoneState(); + + return ( + + {isSpeakingWhileMuted && ( + + You are muted. Unmute to speak. + + )} + + + + + + + + + + + + + + + ); +}; + +const styles = StyleSheet.create({ + speakingLabelContainer: { + backgroundColor: appTheme.colors.static_overlay, + paddingVertical: 10, + width: '100%', + }, + label: { + textAlign: 'center', + color: appTheme.colors.static_white, + }, + callControlsWrapper: { + display: 'flex', + flexDirection: 'row', + justifyContent: 'flex-start', + zIndex: Z_INDEX.IN_FRONT, + }, + container: { + paddingVertical: 16, + paddingHorizontal: 16, + backgroundColor: 'black', + height: 76, + }, + left: { + flex: 2.5, + flexDirection: 'row', + alignItems: 'flex-start', + gap: 6, + }, + right: { + flex: 1, + flexDirection: 'row', + justifyContent: 'flex-end', + gap: 6, + }, +}); diff --git a/sample-apps/react-native/dogfood/src/components/CallControlls/ChatButton.tsx b/sample-apps/react-native/dogfood/src/components/CallControlls/ChatButton.tsx new file mode 100644 index 0000000000..dce03ccb20 --- /dev/null +++ b/sample-apps/react-native/dogfood/src/components/CallControlls/ChatButton.tsx @@ -0,0 +1,45 @@ +import React from 'react'; +import { + CallControlsButton, + useTheme, +} from '@stream-io/video-react-native-sdk'; +import { IconWrapper } from '@stream-io/video-react-native-sdk/src/icons'; +import { BadgeCountIndicator } from './BadgeCountIndicator'; +import Chat from '../../assets/Chat'; + +/** + * The props for the Chat Button in the Call Controls. + */ +export type ChatButtonProps = { + /** + * Handler to be called when the chat button is pressed. + * @returns void + */ + onPressHandler?: () => void; + /** + * The count of the current unread message to be displayed above on the Chat button. + */ + unreadBadgeCount?: number; +}; + +/** + * Button to open the Chat window while in the call. + * + * This call also display the unread count indicator/badge is there messages that are unread. + */ +export const ChatButton = ({ + onPressHandler, + unreadBadgeCount, +}: ChatButtonProps) => { + const { + theme: { colors, chatButton, defaults }, + } = useTheme(); + return ( + + + + + + + ); +}; diff --git a/sample-apps/react-native/dogfood/src/components/CallControlls/MoreActionsButton.tsx b/sample-apps/react-native/dogfood/src/components/CallControlls/MoreActionsButton.tsx new file mode 100644 index 0000000000..a884cadd37 --- /dev/null +++ b/sample-apps/react-native/dogfood/src/components/CallControlls/MoreActionsButton.tsx @@ -0,0 +1,56 @@ +import React, { useState } from 'react'; +import { + CallControlsButton, + useTheme, +} from '@stream-io/video-react-native-sdk'; +import { IconWrapper } from '@stream-io/video-react-native-sdk/src/icons'; +import MoreActions from '../../assets/MoreActions'; + +/** + * The props for the More Actions Button in the Call Controls. + */ +export type MoreActionsButtonProps = { + /** + * Handler to be called when the more actions button is pressed. + */ + onPressHandler?: () => void; +}; + +/** + * A button that can be used to toggle the visibility + * of a menu or bottom sheet with more actions. + * + */ +export const MoreActionsButton = ({ + onPressHandler, +}: MoreActionsButtonProps) => { + const { + theme: { colors, moreActionsButton, defaults }, + } = useTheme(); + + const [isPressed, setIsPressed] = useState(false); + const buttonColor = isPressed + ? colors.buttonPrimaryDefault + : colors.buttonSecondaryDefault; + + return ( + { + // TODO: Implement PBE-5870 [Demo App] Component for "More" menu items + if (onPressHandler) { + onPressHandler(); + } + setIsPressed(!isPressed); + }} + style={moreActionsButton} + color={buttonColor} + > + + + + + ); +}; diff --git a/sample-apps/react-native/dogfood/src/components/CallControlls/ParticipantsButton.tsx b/sample-apps/react-native/dogfood/src/components/CallControlls/ParticipantsButton.tsx new file mode 100644 index 0000000000..593cd5981c --- /dev/null +++ b/sample-apps/react-native/dogfood/src/components/CallControlls/ParticipantsButton.tsx @@ -0,0 +1,68 @@ +import React from 'react'; +import { + CallControlsButton, + useTheme, +} from '@stream-io/video-react-native-sdk'; +import { IconWrapper } from '@stream-io/video-react-native-sdk/src/icons'; +import { useCallStateHooks } from '@stream-io/video-react-bindings'; +import { CallingState } from '@stream-io/video-client'; +import { BadgeCountIndicator } from './BadgeCountIndicator'; +import Participants from '../../assets/Participants'; + +/** + * The props for the Participants Button in the Call Controls. + */ +export type ParticipantsButtonProps = { + /** + * Handler to be called when the participants button is pressed. + * @returns void + */ + onParticipantInfoPress?: () => void; + /** + * The count of the current participants present in the call. + */ + participantCount?: number; +}; + +/** + * Button to open the Participant window while in the call. + * + * This button also displays the participant count of the participants in the call. + */ +export const ParticipantsButton = ({ + onParticipantInfoPress, + participantCount, +}: ParticipantsButtonProps) => { + const { + theme: { colors, chatButton, defaults }, + } = useTheme(); + + const { useCallMembers, useCallCallingState } = useCallStateHooks(); + const members = useCallMembers(); + const callingState = useCallCallingState(); + + let count = 0; + /** + * We show member's length if Incoming and Outgoing Call Views are rendered. + * Else we show the count of the participants that are in the call. + * Since the members count also includes caller/callee, we reduce the count by 1. + **/ + if (callingState === CallingState.RINGING) { + count = members.length - 1; + } else { + count = participantCount ?? 0; + } + + // TODO: PBE-5873 [Demo App] On click implement showing the Participant List + return ( + + + + + + + ); +}; diff --git a/sample-apps/react-native/dogfood/src/components/CallControlls/RecordCallButton.tsx b/sample-apps/react-native/dogfood/src/components/CallControlls/RecordCallButton.tsx new file mode 100644 index 0000000000..7f80e3e406 --- /dev/null +++ b/sample-apps/react-native/dogfood/src/components/CallControlls/RecordCallButton.tsx @@ -0,0 +1,54 @@ +import React, { useState } from 'react'; +import { + CallControlsButton, + useTheme, +} from '@stream-io/video-react-native-sdk'; +import RecordCall from '../../assets/RecordCall'; +import { IconWrapper } from '@stream-io/video-react-native-sdk/src/icons'; + +/** + * The props for the Record Call Button in the Call Controls. + */ +export type RecordCallButtonProps = { + /** + * Handler to be called when the record call button is pressed. + * @returns void + */ + onPressHandler?: () => void; +}; + +/** + * The Record Call Button is used in the Call Controls component + * and allows the user to toggle call recording. + */ +export const RecordCallButton = ({ onPressHandler }: RecordCallButtonProps) => { + const { + theme: { colors, recordCallButton, defaults, variants }, + } = useTheme(); + const [isRecording, setIsRecording] = useState(false); + const buttonColor = isRecording + ? colors.buttonSecondaryWarningDefault + : colors.buttonSecondaryDefault; + + // TODO: implement PBE-5871 [Demo App] Call Recording flow + return ( + { + if (onPressHandler) { + onPressHandler(); + } + setIsRecording(!isRecording); + }} + color={buttonColor} + style={recordCallButton} + > + + + + + ); +}; diff --git a/sample-apps/react-native/dogfood/src/components/CallControlsComponent.tsx b/sample-apps/react-native/dogfood/src/components/CallControlsComponent.tsx deleted file mode 100644 index 9e20823073..0000000000 --- a/sample-apps/react-native/dogfood/src/components/CallControlsComponent.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import { - CallContentProps, - ChatButton, - HangUpCallButton, - ReactionsButton, - ToggleAudioPublishingButton, - ToggleCameraFaceButton, - ToggleVideoPublishingButton, - ScreenShareToggleButton, - useCallStateHooks, -} from '@stream-io/video-react-native-sdk'; -import React from 'react'; -import { StyleSheet, Text, View, ViewStyle } from 'react-native'; -import { appTheme } from '../theme'; -import { useSafeAreaInsets } from 'react-native-safe-area-context'; -import { Z_INDEX } from '../constants'; -import { VideoEffectsButton } from './VideoEffectsButton'; - -export type CallControlsComponentProps = Pick< - CallContentProps, - 'supportedReactions' -> & { - onChatOpenHandler?: () => void; - onHangupCallHandler?: () => void; - unreadCountIndicator?: number; - landscape?: boolean; -}; - -export const CallControlsComponent = ({ - onChatOpenHandler, - onHangupCallHandler, - unreadCountIndicator, - landscape, -}: CallControlsComponentProps) => { - const { bottom } = useSafeAreaInsets(); - const { useMicrophoneState } = useCallStateHooks(); - const { isSpeakingWhileMuted } = useMicrophoneState(); - const landscapeStyles: ViewStyle = { - flexDirection: landscape ? 'column-reverse' : 'row', - paddingHorizontal: landscape ? 12 : 0, - paddingVertical: landscape ? 0 : 12, - paddingBottom: landscape ? 0 : Math.max(bottom, appTheme.spacing.lg), - }; - - return ( - - {isSpeakingWhileMuted && ( - - You are muted. Unmute to speak. - - )} - - - - - - - - - - - - ); -}; - -const styles = StyleSheet.create({ - speakingLabelContainer: { - backgroundColor: appTheme.colors.static_overlay, - paddingVertical: 10, - width: '100%', - }, - label: { - textAlign: 'center', - color: appTheme.colors.static_white, - }, - callControlsWrapper: { - justifyContent: 'space-evenly', - zIndex: Z_INDEX.IN_FRONT, - backgroundColor: appTheme.colors.static_grey, - }, -}); diff --git a/sample-apps/react-native/dogfood/src/components/LiveStream/LiveStreamChatControlButton.tsx b/sample-apps/react-native/dogfood/src/components/LiveStream/LiveStreamChatControlButton.tsx index 87214f0939..ee39eb8dbc 100644 --- a/sample-apps/react-native/dogfood/src/components/LiveStream/LiveStreamChatControlButton.tsx +++ b/sample-apps/react-native/dogfood/src/components/LiveStream/LiveStreamChatControlButton.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { Pressable, View } from 'react-native'; import { appTheme } from '../../theme'; -import { Chat } from '../../assets/Chat'; +import { LiveStreamChat } from '../../assets/LiveStreamChat'; import { StyleSheet } from 'react-native'; type LiveStreamChatControlButtonProps = { @@ -22,7 +22,7 @@ export const LiveStreamChatControlButton = ({ ]} > - + ); diff --git a/sample-apps/react-native/dogfood/src/components/MeetingUI.tsx b/sample-apps/react-native/dogfood/src/components/MeetingUI.tsx index dcae405b3e..f17a03e19a 100644 --- a/sample-apps/react-native/dogfood/src/components/MeetingUI.tsx +++ b/sample-apps/react-native/dogfood/src/components/MeetingUI.tsx @@ -130,7 +130,6 @@ export const MeetingUI = ({ callId, navigation, route }: Props) => { onCallEnded={onCallEnded} onChatOpenHandler={onChatOpenHandler} unreadCountIndicator={unreadCountIndicator} - onHangupCallHandler={onHangupCallHandler} onBackPressed={onHangupCallHandler} /> ); diff --git a/sample-apps/react-native/dogfood/src/components/VideoWrapper.tsx b/sample-apps/react-native/dogfood/src/components/VideoWrapper.tsx index 146075ddc5..9a4064b285 100644 --- a/sample-apps/react-native/dogfood/src/components/VideoWrapper.tsx +++ b/sample-apps/react-native/dogfood/src/components/VideoWrapper.tsx @@ -9,8 +9,10 @@ import { } from '../contexts/AppContext'; import { createToken } from '../modules/helpers/createToken'; import translations from '../translations'; +import { useCustomTheme } from '../theme'; export const VideoWrapper = ({ children }: PropsWithChildren<{}>) => { + const customTheme = useCustomTheme(); const userId = useAppGlobalStoreValue((store) => store.userId); const userName = useAppGlobalStoreValue((store) => store.userName); const userImageUrl = useAppGlobalStoreValue((store) => store.userImageUrl); @@ -64,7 +66,11 @@ export const VideoWrapper = ({ children }: PropsWithChildren<{}>) => { } return ( - + {children} ); diff --git a/sample-apps/react-native/dogfood/src/theme.ts b/sample-apps/react-native/dogfood/src/theme.ts index c1621e8d93..e144d412f8 100644 --- a/sample-apps/react-native/dogfood/src/theme.ts +++ b/sample-apps/react-native/dogfood/src/theme.ts @@ -1,3 +1,6 @@ +import { DeepPartial, Theme } from '@stream-io/video-react-native-sdk'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; + const opacityToHex = (opacity: number) => { return Math.round(opacity * 255) .toString(16) @@ -30,3 +33,17 @@ export const appTheme = { IN_FRONT: 2, }, }; + +export const useCustomTheme = (): DeepPartial => { + const { top, right, bottom, left } = useSafeAreaInsets(); + return { + variants: { + insets: { + top, + right, + bottom, + left, + }, + }, + } as DeepPartial; +}; From d5c047438fa8d1e9722676a1149d24144e171f68 Mon Sep 17 00:00:00 2001 From: Kristian Date: Thu, 24 Oct 2024 13:58:50 +0200 Subject: [PATCH 03/35] feat(design-v2): call scene container and top call components (#1519) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## ๐ŸŽฏ Goal - Jira Tickets: - [PBE-5858](https://stream-io.atlassian.net/browse/PBE-5858) [Demo App] Call Scene container - [PBE-5859](https://stream-io.atlassian.net/browse/PBE-5859) [Demo App] Call Duration / Recording badge + UI Cookbook ## ๐Ÿ›  Implementation details - adds new - top call controls component - reuses the hangup call button - add new controls for layout switcher, video effects and camera swticher - call status badge (showing the call duration or call recording message if the call is recorded) - improves the Participant view - new stylings for the network quality status - adds new speech indicator component ## ๐ŸŽจ UI Changes iOS
Before After
ios-before ios-after
[PBE-5858]: https://stream-io.atlassian.net/browse/PBE-5858?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ [PBE-5859]: https://stream-io.atlassian.net/browse/PBE-5859?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ --- .../Call/CallContent/CallContent.tsx | 19 +-- .../Call/CallControls/CallControlsButton.tsx | 7 +- .../Call/CallControls/HangupCallButton.tsx | 18 +-- .../Call/CallControls/RejectCallButton.tsx | 4 +- .../CallControls/ToggleCameraFaceButton.tsx | 26 ++-- .../Call/CallLayout/CallParticipantsGrid.tsx | 6 +- .../CallParticipantsList.tsx | 4 +- .../Call/CallTopView/CallTopView.tsx | 140 ------------------ .../src/components/Call/CallTopView/index.ts | 1 - .../Call/RingingCallContent/IncomingCall.tsx | 8 +- .../Call/RingingCallContent/OutgoingCall.tsx | 8 +- .../RingingCallContent/RingingCallContent.tsx | 3 +- .../src/components/Call/index.ts | 1 - .../ParticipantView/ParticipantLabel.tsx | 117 ++++++++------- .../ParticipantNetworkQualityIndicator.tsx | 22 ++- .../ParticipantView/ParticipantView.tsx | 45 +++--- .../ParticipantView/SpeechIndicator.tsx | 105 +++++++++++++ .../src/icons/CameraSwitch.tsx | 7 +- .../react-native-sdk/src/icons/Effects.tsx | 17 +++ packages/react-native-sdk/src/icons/Grid.tsx | 17 +++ .../react-native-sdk/src/icons/PhoneDown.tsx | 12 +- .../react-native-sdk/src/icons/RecordCall.tsx | 21 +++ packages/react-native-sdk/src/theme/colors.ts | 2 +- .../react-native/dogfood/ios/Podfile.lock | 13 +- .../dogfood/src/assets/CallDuration.tsx | 17 +++ .../dogfood/src/assets/RecordCall.tsx | 23 --- .../dogfood/src/components/ActiveCall.tsx | 35 +++-- .../dogfood/src/components/Button.tsx | 27 +++- ...ntrolsComponent.tsx => BottomControls.tsx} | 86 ++++++----- .../CallControlls/CallStatusBadge.tsx | 105 +++++++++++++ .../CallControlls/LayoutSwitcherButton.tsx | 48 ++++++ .../CallControlls/RecordCallButton.tsx | 6 +- .../components/CallControlls/TopControls.tsx | 95 ++++++++++++ .../dogfood/src/components/MeetingUI.tsx | 2 +- .../components/VideoEffectsButton/index.tsx | 18 ++- .../ChannelHeader/ChannelHeader.tsx | 5 +- .../src/components/QuickDial/QuickDial.tsx | 6 +- 37 files changed, 717 insertions(+), 379 deletions(-) delete mode 100644 packages/react-native-sdk/src/components/Call/CallTopView/CallTopView.tsx delete mode 100644 packages/react-native-sdk/src/components/Call/CallTopView/index.ts create mode 100644 packages/react-native-sdk/src/components/Participant/ParticipantView/SpeechIndicator.tsx create mode 100644 packages/react-native-sdk/src/icons/Effects.tsx create mode 100644 packages/react-native-sdk/src/icons/Grid.tsx create mode 100644 packages/react-native-sdk/src/icons/RecordCall.tsx create mode 100644 sample-apps/react-native/dogfood/src/assets/CallDuration.tsx delete mode 100644 sample-apps/react-native/dogfood/src/assets/RecordCall.tsx rename sample-apps/react-native/dogfood/src/components/CallControlls/{CallControlsComponent.tsx => BottomControls.tsx} (57%) create mode 100644 sample-apps/react-native/dogfood/src/components/CallControlls/CallStatusBadge.tsx create mode 100644 sample-apps/react-native/dogfood/src/components/CallControlls/LayoutSwitcherButton.tsx create mode 100644 sample-apps/react-native/dogfood/src/components/CallControlls/TopControls.tsx diff --git a/packages/react-native-sdk/src/components/Call/CallContent/CallContent.tsx b/packages/react-native-sdk/src/components/Call/CallContent/CallContent.tsx index 2539652703..0ec66f8df2 100644 --- a/packages/react-native-sdk/src/components/Call/CallContent/CallContent.tsx +++ b/packages/react-native-sdk/src/components/Call/CallContent/CallContent.tsx @@ -1,11 +1,6 @@ import React, { useEffect, useState } from 'react'; import { StyleSheet, View } from 'react-native'; import InCallManager from 'react-native-incall-manager'; - -import { - CallTopView as DefaultCallTopView, - CallTopViewProps, -} from '../CallTopView'; import { CallParticipantsGrid, CallParticipantsGridProps, @@ -48,7 +43,7 @@ type CallContentComponentProps = ParticipantViewComponentProps & /** * Component to customize the CallTopView component. */ - CallTopView?: React.ComponentType | null; + CallTopView?: React.ComponentType | null; /** * Component to customize the CallControls component. */ @@ -71,7 +66,6 @@ export type CallContentProps = Pick< HangUpCallButtonProps, 'onHangupCallHandler' > & - Pick & CallContentComponentProps & { /** * This switches the participant's layout between the grid and the spotlight mode. @@ -97,10 +91,9 @@ export type CallContentProps = Pick< }; export const CallContent = ({ - onBackPressed, onHangupCallHandler, CallParticipantsList, - CallTopView = DefaultCallTopView, + CallTopView, CallControls = DefaultCallControls, FloatingParticipantView = DefaultFloatingParticipantView, ScreenShareOverlay = DefaultScreenShareOverlay, @@ -204,16 +197,16 @@ export const CallContent = ({ /> )} - + + {!isInPiPMode && CallTopView && ( + + )} - {!isInPiPMode && CallTopView && ( - - )} {showFloatingView && FloatingParticipantView && ( { @@ -72,15 +73,12 @@ export const HangUpCallButton = ({ size={size} testID={ButtonTestIds.HANG_UP_CALL} > - + + + ); }; - -// TODO: Check if this style is needed -// This was passed to CallControlsButton as style prop -// const styles = StyleSheet.create({ -// button: { -// shadowColor: theme.light.error, -// }, -// }); diff --git a/packages/react-native-sdk/src/components/Call/CallControls/RejectCallButton.tsx b/packages/react-native-sdk/src/components/Call/CallControls/RejectCallButton.tsx index f1a3c5372b..8073c6a7f8 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/RejectCallButton.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/RejectCallButton.tsx @@ -38,7 +38,7 @@ export const RejectCallButton = ({ theme: { colors, rejectCallButton, - variants: { buttonSizes }, + variants: { buttonSizes, iconSizes }, }, } = useTheme(); const rejectCallHandler = async () => { @@ -69,7 +69,7 @@ export const RejectCallButton = ({ // svgContainerStyle={theme.icon.lg} style={rejectCallButton} > - + ); }; diff --git a/packages/react-native-sdk/src/components/Call/CallControls/ToggleCameraFaceButton.tsx b/packages/react-native-sdk/src/components/Call/CallControls/ToggleCameraFaceButton.tsx index fa5652f665..ac27479f69 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/ToggleCameraFaceButton.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/ToggleCameraFaceButton.tsx @@ -2,7 +2,7 @@ import { OwnCapability } from '@stream-io/video-client'; import { Restricted, useCallStateHooks } from '@stream-io/video-react-bindings'; import React from 'react'; import { CallControlsButton } from './CallControlsButton'; -import { CameraSwitch } from '../../../icons'; +import { CameraSwitch, IconWrapper } from '../../../icons'; import { useTheme } from '../../../contexts/ThemeContext'; /** @@ -28,7 +28,7 @@ export const ToggleCameraFaceButton = ({ const isVideoEnabledInCall = callSettings?.video.enabled; const { - theme: { colors, toggleCameraFaceButton }, + theme: { colors, toggleCameraFaceButton, defaults }, } = useTheme(); const onPress = async () => { if (onPressHandler) { @@ -47,17 +47,23 @@ export const ToggleCameraFaceButton = ({ - + + + ); diff --git a/packages/react-native-sdk/src/components/Call/CallLayout/CallParticipantsGrid.tsx b/packages/react-native-sdk/src/components/Call/CallLayout/CallParticipantsGrid.tsx index 521f73fc24..d71bb8c128 100644 --- a/packages/react-native-sdk/src/components/Call/CallLayout/CallParticipantsGrid.tsx +++ b/packages/react-native-sdk/src/components/Call/CallLayout/CallParticipantsGrid.tsx @@ -100,7 +100,7 @@ export const CallParticipantsGrid = ({ style={[ styles.container, landscapeStyles, - { backgroundColor: colors.background2 }, + { backgroundColor: colors.sheetPrimary }, callParticipantsGrid.container, ]} testID={ComponentTestIds.CALL_PARTICIPANTS_GRID} @@ -118,7 +118,5 @@ export const CallParticipantsGrid = ({ }; const styles = StyleSheet.create({ - container: { - flex: 1, - }, + container: { flex: 1 }, }); diff --git a/packages/react-native-sdk/src/components/Call/CallParticipantsList/CallParticipantsList.tsx b/packages/react-native-sdk/src/components/Call/CallParticipantsList/CallParticipantsList.tsx index 2bf3a37758..afc4a53309 100644 --- a/packages/react-native-sdk/src/components/Call/CallParticipantsList/CallParticipantsList.tsx +++ b/packages/react-native-sdk/src/components/Call/CallParticipantsList/CallParticipantsList.tsx @@ -252,9 +252,7 @@ export const CallParticipantsList = ({ }; const styles = StyleSheet.create({ - flexed: { - flex: 1, - }, + flexed: { flex: 1 }, participantWrapperHorizontal: { // note: if marginHorizontal is changed, be sure to change the width calculation in calculateParticipantViewSize function marginHorizontal: 8, diff --git a/packages/react-native-sdk/src/components/Call/CallTopView/CallTopView.tsx b/packages/react-native-sdk/src/components/Call/CallTopView/CallTopView.tsx deleted file mode 100644 index e16fed2516..0000000000 --- a/packages/react-native-sdk/src/components/Call/CallTopView/CallTopView.tsx +++ /dev/null @@ -1,140 +0,0 @@ -import React, { useState } from 'react'; -import { - View, - StyleSheet, - Text, - Pressable, - StyleProp, - ViewStyle, -} from 'react-native'; -import { Back } from '../../../icons/Back'; -import { TopViewBackground } from '../../../icons'; -import { useCallStateHooks, useI18n } from '@stream-io/video-react-bindings'; -import { CallingState } from '@stream-io/video-client'; -import { useTheme } from '../../../contexts/ThemeContext'; - -export type CallTopViewProps = { - /** - * Handler to be called when the back button is pressed in the CallTopView. - * @returns void - */ - onBackPressed?: () => void; - /** - * Title to be rendered at the center of the Header. - */ - title?: string; - /** - * Style to override the container of the CallTopView. - */ - style?: StyleProp; -}; - -export const CallTopView = ({ - onBackPressed, - title, - style: styleProp, -}: CallTopViewProps) => { - const [callTopViewHeight, setCallTopViewHeight] = useState(0); - const [callTopViewWidth, setCallTopViewWidth] = useState(0); - const { - theme: { - colors, - typefaces, - variants: { iconSizes }, - callTopView, - }, - } = useTheme(); - const { useCallCallingState } = useCallStateHooks(); - const callingState = useCallCallingState(); - const { t } = useI18n(); - const isCallReconnecting = callingState === CallingState.RECONNECTING; - - const onLayout: React.ComponentProps['onLayout'] = (event) => { - const { height, width } = event.nativeEvent.layout; - if (setCallTopViewHeight) { - setCallTopViewHeight(height); - setCallTopViewWidth(width); - } - }; - - return ( - - {/* Component for the background of the CallTopView. Since it has a Linear Gradient, an SVG is used to render it. */} - - - - {onBackPressed && ( - [ - styles.backIconContainer, - { - opacity: pressed ? 0.2 : 1, - height: iconSizes.md, - width: iconSizes.md, - }, - callTopView.backIconContainer, - ]} - onPress={onBackPressed} - > - - - )} - - - {title ? ( - - {title} - - ) : ( - isCallReconnecting && ( - - {t('Reconnecting...')} - - ) - )} - - - - ); -}; - -const styles = StyleSheet.create({ - content: { - position: 'absolute', - top: 0, - flexDirection: 'row', - paddingTop: 24, - paddingBottom: 12, - alignItems: 'center', - }, - backIconContainer: { - // Added to compensate the participant badge surface area - marginLeft: 8, - }, - leftElement: { - flex: 1, - alignItems: 'flex-start', - }, - centerElement: { - flex: 1, - alignItems: 'center', - flexGrow: 3, - }, - rightElement: { - flex: 1, - alignItems: 'flex-end', - }, -}); diff --git a/packages/react-native-sdk/src/components/Call/CallTopView/index.ts b/packages/react-native-sdk/src/components/Call/CallTopView/index.ts deleted file mode 100644 index bb5d521f5b..0000000000 --- a/packages/react-native-sdk/src/components/Call/CallTopView/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './CallTopView'; diff --git a/packages/react-native-sdk/src/components/Call/RingingCallContent/IncomingCall.tsx b/packages/react-native-sdk/src/components/Call/RingingCallContent/IncomingCall.tsx index 3dca12bedb..074768c24e 100644 --- a/packages/react-native-sdk/src/components/Call/RingingCallContent/IncomingCall.tsx +++ b/packages/react-native-sdk/src/components/Call/RingingCallContent/IncomingCall.tsx @@ -12,10 +12,6 @@ import { useI18n, } from '@stream-io/video-react-bindings'; import { UserInfo } from './UserInfo'; -import { - CallTopView as DefaultCallTopView, - CallTopViewProps, -} from '../CallTopView'; import { IncomingCallControls as DefaultIncomingCallControls, IncomingCallControlsProps, @@ -30,7 +26,7 @@ export type IncomingCallProps = IncomingCallControlsProps & { /** * Prop to customize the CallTopView component in the IncomingCall component. */ - CallTopView?: React.ComponentType | null; + CallTopView?: React.ComponentType | null; /** * Prop to customize the IncomingCall controls. */ @@ -49,7 +45,7 @@ export type IncomingCallProps = IncomingCallControlsProps & { export const IncomingCall = ({ onAcceptCallHandler, onRejectCallHandler, - CallTopView = DefaultCallTopView, + CallTopView, IncomingCallControls = DefaultIncomingCallControls, landscape, }: IncomingCallProps) => { diff --git a/packages/react-native-sdk/src/components/Call/RingingCallContent/OutgoingCall.tsx b/packages/react-native-sdk/src/components/Call/RingingCallContent/OutgoingCall.tsx index ce70a5ab94..fe441098d4 100644 --- a/packages/react-native-sdk/src/components/Call/RingingCallContent/OutgoingCall.tsx +++ b/packages/react-native-sdk/src/components/Call/RingingCallContent/OutgoingCall.tsx @@ -9,10 +9,6 @@ import { OutgoingCallControls as DefaultOutgoingCallControls, OutgoingCallControlsProps, } from '../CallControls'; -import { - CallTopView as DefaultCallTopView, - CallTopViewProps, -} from '../CallTopView'; import { useCallMediaStreamCleanup } from '../../../hooks/internal/useCallMediaStreamCleanup'; import { useApplyDefaultMediaStreamSettings } from '../../../hooks/useApplyDefaultMediaStreamSettings'; @@ -23,7 +19,7 @@ export type OutgoingCallProps = OutgoingCallControlsProps & { /** * Prop to customize the CallTopView component in the IncomingCall component. */ - CallTopView?: React.ComponentType | null; + CallTopView?: React.ComponentType | null; /** * Prop to customize the OutgoingCall controls. */ @@ -40,7 +36,7 @@ export type OutgoingCallProps = OutgoingCallControlsProps & { * Used after the user has initiated a call. */ export const OutgoingCall = ({ - CallTopView = DefaultCallTopView, + CallTopView, OutgoingCallControls = DefaultOutgoingCallControls, landscape, }: OutgoingCallProps) => { diff --git a/packages/react-native-sdk/src/components/Call/RingingCallContent/RingingCallContent.tsx b/packages/react-native-sdk/src/components/Call/RingingCallContent/RingingCallContent.tsx index 18d0524013..f84f222ad0 100644 --- a/packages/react-native-sdk/src/components/Call/RingingCallContent/RingingCallContent.tsx +++ b/packages/react-native-sdk/src/components/Call/RingingCallContent/RingingCallContent.tsx @@ -6,7 +6,6 @@ import { CallContent as DefaultCallContent, CallContentProps, } from '../CallContent'; -import { CallTopViewProps } from '../CallTopView'; import { IncomingCall as DefaultIncomingCall, IncomingCallProps, @@ -44,7 +43,7 @@ export type RingingCallContentProps = { /** * Prop to customize the CallTopView component in the RingingCallContent. */ - CallTopView?: React.ComponentType | null; + CallTopView?: React.ComponentType | null; /** * Prop to override the component shown when the call is left. */ diff --git a/packages/react-native-sdk/src/components/Call/index.ts b/packages/react-native-sdk/src/components/Call/index.ts index 2b099259ff..b86bcd1797 100644 --- a/packages/react-native-sdk/src/components/Call/index.ts +++ b/packages/react-native-sdk/src/components/Call/index.ts @@ -1,5 +1,4 @@ export * from './CallContent'; -export * from './CallTopView'; export * from './CallLayout'; export * from './CallControls'; export * from './CallParticipantsList'; diff --git a/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantLabel.tsx b/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantLabel.tsx index de58feced2..5d4ee2ad81 100644 --- a/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantLabel.tsx +++ b/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantLabel.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useMemo } from 'react'; import { Pressable, StyleSheet, Text, View } from 'react-native'; import { PinVertical, ScreenShareIndicator } from '../../../icons'; import { useCall, useI18n } from '@stream-io/video-react-bindings'; @@ -6,6 +6,7 @@ import { ComponentTestIds } from '../../../constants/TestIds'; import { ParticipantViewProps } from './ParticipantView'; import { Z_INDEX } from '../../../constants'; import { useTheme } from '../../../contexts/ThemeContext'; +import SpeechIndicator from './SpeechIndicator'; /** * Props for the ParticipantLabel component. @@ -35,6 +36,7 @@ export const ParticipantLabel = ({ }, }, } = useTheme(); + const styles = useStyles(); const { name, userId, pin, sessionId, isLocalParticipant } = participant; const call = useCall(); const { t } = useI18n(); @@ -57,7 +59,7 @@ export const ParticipantLabel = ({ - + - - {participantLabel} - + + + {participantLabel} + + + + + {isPinningEnabled && ( - + )} ); }; -const styles = StyleSheet.create({ - container: { - flexDirection: 'row', - alignItems: 'center', - padding: 8, - borderRadius: 5, - flexShrink: 1, - zIndex: Z_INDEX.IN_FRONT, - }, - userNameLabel: { - flexShrink: 1, - }, - screenShareIconContainer: { - marginRight: 8, - }, - audioMutedIconContainer: { - marginLeft: 4, - }, - videoMutedIconContainer: { - marginLeft: 4, - }, - pinIconContainer: { - marginLeft: 4, - }, -}); +const useStyles = () => { + const { theme } = useTheme(); + return useMemo( + () => + StyleSheet.create({ + indicatorWrapper: { + marginLeft: theme.variants.spacingSizes.sm, + }, + wrapper: { + flexDirection: 'row', + }, + container: { + flexDirection: 'row', + alignItems: 'center', + padding: theme.variants.spacingSizes.sm, + maxHeight: 30, + borderTopRightRadius: 5, + marginBottom: -2, + flexShrink: 1, + zIndex: Z_INDEX.IN_FRONT, + }, + userNameLabel: { + flexShrink: 1, + marginTop: 2, + }, + screenShareIconContainer: { + marginRight: theme.variants.spacingSizes.sm, + }, + audioMutedIconContainer: { + marginLeft: theme.variants.spacingSizes.xs, + }, + videoMutedIconContainer: { + marginLeft: theme.variants.spacingSizes.xs, + }, + pinIconContainer: { + marginLeft: theme.variants.spacingSizes.xs, + }, + }), + [theme] + ); +}; diff --git a/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantNetworkQualityIndicator.tsx b/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantNetworkQualityIndicator.tsx index 1e768bcf96..fd39d74f47 100644 --- a/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantNetworkQualityIndicator.tsx +++ b/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantNetworkQualityIndicator.tsx @@ -27,11 +27,23 @@ const useConnectionQualitySignalColors = ( switch (connectionQuality) { case SfuModels.ConnectionQuality.EXCELLENT: - return [colors.primary, colors.primary, colors.primary]; + return [ + colors.iconAlertSuccess, + colors.iconAlertSuccess, + colors.iconAlertSuccess, + ]; case SfuModels.ConnectionQuality.GOOD: - return [colors.primary, colors.primary, colors.base1]; + return [ + colors.iconAlertSuccess, + colors.iconAlertSuccess, + colors.iconPrimaryDefault, + ]; case SfuModels.ConnectionQuality.POOR: - return [colors.error, colors.base1, colors.base1]; + return [ + colors.iconAlertWarning, + colors.iconPrimaryDefault, + colors.iconPrimaryDefault, + ]; default: return null; } @@ -57,7 +69,7 @@ export const ParticipantNetworkQualityIndicator = ({ style={[ styles.container, { - backgroundColor: colors.background6, + backgroundColor: colors.sheetOverlay, height: iconSizes.lg, width: iconSizes.lg, }, @@ -98,6 +110,6 @@ const styles = StyleSheet.create({ container: { zIndex: Z_INDEX.IN_FRONT, alignSelf: 'flex-end', - borderRadius: 5, + borderTopLeftRadius: 5, }, }); diff --git a/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantView.tsx b/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantView.tsx index 09a4037dbd..76b6e74921 100644 --- a/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantView.tsx +++ b/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantView.tsx @@ -1,4 +1,4 @@ -import React, { ComponentType } from 'react'; +import React, { ComponentType, useMemo } from 'react'; import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native'; import { StreamVideoParticipant, @@ -112,6 +112,7 @@ export const ParticipantView = ({ const { theme: { colors, participantView }, } = useTheme(); + const styles = useStyles(); const { isSpeaking, userId } = participant; const isScreenSharing = trackType === 'screenShareTrack'; const applySpeakerStyle = isSpeaking && !isScreenSharing; @@ -160,20 +161,28 @@ export const ParticipantView = ({ ); }; -const styles = StyleSheet.create({ - container: { - justifyContent: 'space-between', - padding: 4, - overflow: 'hidden', - borderWidth: 2, - borderColor: 'transparent', - }, - footerContainer: { - flexDirection: 'row', - justifyContent: 'space-between', - alignItems: 'center', - }, - highligtedContainer: { - borderWidth: 2, - }, -}); +const useStyles = () => { + const { theme } = useTheme(); + return useMemo( + () => + StyleSheet.create({ + container: { + justifyContent: 'space-between', + overflow: 'hidden', + borderWidth: 2, + borderColor: 'transparent', + margin: theme.variants.spacingSizes.sm, + borderRadius: 16, + }, + footerContainer: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + }, + highligtedContainer: { + borderWidth: 2, + }, + }), + [theme] + ); +}; diff --git a/packages/react-native-sdk/src/components/Participant/ParticipantView/SpeechIndicator.tsx b/packages/react-native-sdk/src/components/Participant/ParticipantView/SpeechIndicator.tsx new file mode 100644 index 0000000000..d7d78633aa --- /dev/null +++ b/packages/react-native-sdk/src/components/Participant/ParticipantView/SpeechIndicator.tsx @@ -0,0 +1,105 @@ +import React, { useEffect, useRef, useMemo } from 'react'; +import { View, Animated, StyleSheet } from 'react-native'; +import { useTheme } from '../../..'; + +/** + * Props for the SpeechIndicator component. + */ +export type SpeechIndicatorProps = { + /** + * Indicates whether the participant is speaking. + * If true, the animation will run, otherwise the bars will remain static. + */ + isSpeaking: boolean; +}; + +/** + * The SpeechIndicator component displays animated bars to indicate speech activity. + * The bars animate when `isSpeaking` is true, mimicking a sound meter. + */ +export const SpeechIndicator = ({ isSpeaking }: SpeechIndicatorProps) => { + const styles = useStyles(); + const animatedValue1 = useRef(new Animated.Value(0.6)).current; + const animatedValue2 = useRef(new Animated.Value(0.6)).current; + const animatedValue3 = useRef(new Animated.Value(0.6)).current; + + const animationValues = useMemo( + () => [animatedValue1, animatedValue2, animatedValue3], + [animatedValue1, animatedValue2, animatedValue3] + ); + + useEffect(() => { + if (isSpeaking) { + animationValues.forEach((animatedValue, index) => { + Animated.loop( + Animated.sequence([ + Animated.timing(animatedValue, { + toValue: index % 2 === 0 ? 0.3 : 1.1, + duration: (index + 1) * 300, + useNativeDriver: true, + }), + Animated.timing(animatedValue, { + toValue: 0.6, + duration: (index + 1) * 300, + useNativeDriver: true, + }), + ]) + ).start(); + }); + } else { + animationValues.forEach((animatedValue) => { + animatedValue.setValue(0.3); // Set a smaller value for a reduced default height + }); + } + }, [isSpeaking, animationValues]); + + const barStyle = (animatedValue: Animated.Value) => ({ + transform: [{ scaleY: animatedValue }], + }); + + return ( + + {animationValues.map((animatedValue, index) => ( + + ))} + + ); +}; + +const useStyles = () => { + const { theme } = useTheme(); + return useMemo( + () => + StyleSheet.create({ + container: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + height: theme.variants.roundButtonSizes.sm, + width: theme.variants.roundButtonSizes.sm, + borderRadius: 5, + gap: 1, + backgroundColor: theme.colors.sheetOverlay, + padding: 5, + }, + smallBar: { + height: '30%', // Smaller default height when animation is not running + }, + bar: { + width: 3, + height: '100%', + backgroundColor: theme.colors.iconPrimaryAccent, + borderRadius: 2, + }, + }), + [theme] + ); +}; + +export default SpeechIndicator; diff --git a/packages/react-native-sdk/src/icons/CameraSwitch.tsx b/packages/react-native-sdk/src/icons/CameraSwitch.tsx index 9839d7cffd..a4fc8aa5f9 100644 --- a/packages/react-native-sdk/src/icons/CameraSwitch.tsx +++ b/packages/react-native-sdk/src/icons/CameraSwitch.tsx @@ -4,12 +4,13 @@ import { ColorValue } from 'react-native/types'; type Props = { color: ColorValue; + size: number; }; -export const CameraSwitch = ({ color }: Props) => ( - +export const CameraSwitch = ({ color, size }: Props) => ( + diff --git a/packages/react-native-sdk/src/icons/Effects.tsx b/packages/react-native-sdk/src/icons/Effects.tsx new file mode 100644 index 0000000000..c2629712bc --- /dev/null +++ b/packages/react-native-sdk/src/icons/Effects.tsx @@ -0,0 +1,17 @@ +import React from 'react'; +import { Svg, Path } from 'react-native-svg'; +import { ColorValue } from 'react-native/types'; + +type Props = { + color: ColorValue; + size: number; +}; + +export const Effects = ({ color, size }: Props) => ( + + + +); diff --git a/packages/react-native-sdk/src/icons/Grid.tsx b/packages/react-native-sdk/src/icons/Grid.tsx new file mode 100644 index 0000000000..2f64742f5f --- /dev/null +++ b/packages/react-native-sdk/src/icons/Grid.tsx @@ -0,0 +1,17 @@ +import React from 'react'; +import { Svg, Path } from 'react-native-svg'; +import { ColorValue } from 'react-native/types'; + +type Props = { + color: ColorValue; + size: number; +}; + +export const Grid = ({ color, size }: Props) => ( + + + +); diff --git a/packages/react-native-sdk/src/icons/PhoneDown.tsx b/packages/react-native-sdk/src/icons/PhoneDown.tsx index 14a92d3737..346f5aa971 100644 --- a/packages/react-native-sdk/src/icons/PhoneDown.tsx +++ b/packages/react-native-sdk/src/icons/PhoneDown.tsx @@ -5,12 +5,18 @@ import { IconTestIds } from '../constants/TestIds'; type Props = { color: ColorValue; + size: number; }; -export const PhoneDown = ({ color }: Props) => ( - +export const PhoneDown = ({ color, size }: Props) => ( + diff --git a/packages/react-native-sdk/src/icons/RecordCall.tsx b/packages/react-native-sdk/src/icons/RecordCall.tsx new file mode 100644 index 0000000000..c1b9853f42 --- /dev/null +++ b/packages/react-native-sdk/src/icons/RecordCall.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { ColorValue } from 'react-native'; +import { Svg, Path } from 'react-native-svg'; + +type Props = { + color: ColorValue; + size: number; +}; + +export const RecordCall = ({ color, size }: Props) => ( + + + + +); diff --git a/packages/react-native-sdk/src/theme/colors.ts b/packages/react-native-sdk/src/theme/colors.ts index 39c3beb0d3..0c78ae81db 100644 --- a/packages/react-native-sdk/src/theme/colors.ts +++ b/packages/react-native-sdk/src/theme/colors.ts @@ -35,6 +35,7 @@ const colors: ColorScheme = { iconPrimaryDefault: '#eff0f1', iconAlertSuccess: '#00e2a1', sheetPrimary: '#000000', + sheetOverlay: '#0c0d0ea6', buttonPrimaryDisabled: '#1b2c43', buttonPrimaryHover: '#4c8fff', @@ -71,7 +72,6 @@ const colors: ColorScheme = { iconPrimaryHover: '#e3e4e5', iconPrimaryOnAccent: '#eff0f1', iconPrimaryPressed: '#656b72', - sheetOverlay: '#0c0d0ea6', sheetSecondary: '#101213', sheetTertiary: '#19232d', typeAccent: '#00e2a1', diff --git a/sample-apps/react-native/dogfood/ios/Podfile.lock b/sample-apps/react-native/dogfood/ios/Podfile.lock index 88d6484ca8..dcd202c2c3 100644 --- a/sample-apps/react-native/dogfood/ios/Podfile.lock +++ b/sample-apps/react-native/dogfood/ios/Podfile.lock @@ -916,7 +916,7 @@ PODS: - React-Core - react-native-netinfo (11.3.0): - React-Core - - react-native-safe-area-context (4.8.2): + - react-native-safe-area-context (4.10.5): - React-Core - react-native-video (6.0.0-beta.5): - React-Core @@ -1126,15 +1126,16 @@ PODS: - React-Core - RNReactNativeHapticFeedback (2.0.3): - React-Core - - RNReanimated (3.7.0): + - RNReanimated (3.10.1): - glog - RCT-Folly (= 2022.05.16.00) - React-Core - ReactCommon/turbomodule/core - - RNScreens (3.29.0): + - RNScreens (3.31.1): - glog - RCT-Folly (= 2022.05.16.00) - React-Core + - React-RCTImage - RNSVG (13.9.0): - React-Core - RNVoipPushNotification (3.3.2): @@ -1439,7 +1440,7 @@ SPEC CHECKSUMS: react-native-image-resizer: d9fb629a867335bdc13230ac2a58702bb8c8828f react-native-mmkv: 7da5e18e55c04a9af9a7e0ab9792a1e8d33765a1 react-native-netinfo: 299dad906cdbf3b67bcc6f693c807f98bdd127cc - react-native-safe-area-context: 0ee144a6170530ccc37a0fd9388e28d06f516a89 + react-native-safe-area-context: a240ad4b683349e48b1d51fed1611138d1bdad97 react-native-video: df7d8a4c8568ed4a31b28e6cd2bfa4a98b186e36 React-nativeconfig: ca8b90c736cf3be019cb332ca42d93dd95b32e05 React-NativeModulesApple: 1fdffcce7772e274baeab33a1900f45feba86cbd @@ -1472,8 +1473,8 @@ SPEC CHECKSUMS: RNNotifee: f3c01b391dd8e98e67f539f9a35a9cbcd3bae744 RNPermissions: 4d64d2c763b20e5db08dfb8f1ef541f95c0d28c1 RNReactNativeHapticFeedback: afa5bf2794aecbb2dba2525329253da0d66656df - RNReanimated: ea7e98bf4f1167ca3cd3c348604d34dc4294e848 - RNScreens: 2b73f5eb2ac5d94fbd61fa4be0bfebd345716825 + RNReanimated: 8cd12e58bbedca2b0b62a3c3872d3629fc2e1583 + RNScreens: 35f3344904f6bba888c0e61532278436e275de3c RNSVG: 53c661b76829783cdaf9b7a57258f3d3b4c28315 RNVoipPushNotification: 543e18f83089134a35e7f1d2eba4c8b1f7776b08 SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17 diff --git a/sample-apps/react-native/dogfood/src/assets/CallDuration.tsx b/sample-apps/react-native/dogfood/src/assets/CallDuration.tsx new file mode 100644 index 0000000000..70c0e04b8e --- /dev/null +++ b/sample-apps/react-native/dogfood/src/assets/CallDuration.tsx @@ -0,0 +1,17 @@ +import React from 'react'; +import { Svg, Path } from 'react-native-svg'; +import { ColorValue } from 'react-native/types'; + +type Props = { + color: ColorValue; + size: number; +}; + +export const CallDuration = ({ color, size }: Props) => ( + + + +); diff --git a/sample-apps/react-native/dogfood/src/assets/RecordCall.tsx b/sample-apps/react-native/dogfood/src/assets/RecordCall.tsx deleted file mode 100644 index c07c995b43..0000000000 --- a/sample-apps/react-native/dogfood/src/assets/RecordCall.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import React from 'react'; -import { ColorValue } from 'react-native'; -import { Svg, Path } from 'react-native-svg'; - -type Props = { - color: ColorValue; - size: number; -}; - -const RecordCall = ({ color, size }: Props) => ( - - - - -); - -export default RecordCall; diff --git a/sample-apps/react-native/dogfood/src/components/ActiveCall.tsx b/sample-apps/react-native/dogfood/src/components/ActiveCall.tsx index 1f61e00fac..0ed9194ab4 100644 --- a/sample-apps/react-native/dogfood/src/components/ActiveCall.tsx +++ b/sample-apps/react-native/dogfood/src/components/ActiveCall.tsx @@ -4,24 +4,25 @@ import { CallContent, useTheme, } from '@stream-io/video-react-native-sdk'; -import { ActivityIndicator, StyleSheet, View } from 'react-native'; +import { ActivityIndicator, StatusBar, StyleSheet, View } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { ParticipantsInfoList } from './ParticipantsInfoList'; import { CallControlsComponent, - CallControlsComponentProps, -} from './CallControlls/CallControlsComponent'; + BottomControlsProps, +} from './CallControlls/BottomControls'; import { useOrientation } from '../hooks/useOrientation'; import { Z_INDEX } from '../constants'; +import { TopControls } from './CallControlls/TopControls'; -type ActiveCallProps = CallControlsComponentProps & { - onBackPressed?: () => void; +type ActiveCallProps = BottomControlsProps & { + onHangupCallHandler?: () => void; onCallEnded: () => void; }; export const ActiveCall = ({ onChatOpenHandler, - onBackPressed, + onHangupCallHandler, onCallEnded, unreadCountIndicator, }: ActiveCallProps) => { @@ -30,6 +31,7 @@ export const ActiveCall = ({ const call = useCall(); const currentOrientation = useOrientation(); const styles = useStyles(); + const { theme: colors } = useTheme(); const onOpenCallParticipantsInfo = useCallback(() => { setIsCallParticipantsVisible(true); @@ -57,9 +59,15 @@ export const ActiveCall = ({ return ( + + @@ -68,7 +76,7 @@ export const ActiveCall = ({ setIsCallParticipantsInfoVisible={setIsCallParticipantsVisible} /> - + ); }; @@ -82,7 +90,16 @@ const useStyles = () => { container: { flex: 1 }, callContent: { flex: 1 }, safeArea: { flex: 1, paddingBottom: theme.variants.insets.bottom }, - unsafeArea: { + topUnsafeArea: { + position: 'absolute', + top: 0, + left: 0, + right: 0, + height: theme.variants.insets.top, + backgroundColor: theme.colors.sheetPrimary, + zIndex: Z_INDEX.IN_FRONT, + }, + bottomUnsafeArea: { position: 'absolute', left: 0, right: 0, diff --git a/sample-apps/react-native/dogfood/src/components/Button.tsx b/sample-apps/react-native/dogfood/src/components/Button.tsx index 21f7a7b4a1..889a1dd01a 100644 --- a/sample-apps/react-native/dogfood/src/components/Button.tsx +++ b/sample-apps/react-native/dogfood/src/components/Button.tsx @@ -9,7 +9,11 @@ import { ViewStyle, } from 'react-native'; import { BUTTON_HEIGHT } from '../constants'; -import { useTheme } from '@stream-io/video-react-native-sdk'; +import { + Theme, + defaultTheme, + useTheme, +} from '@stream-io/video-react-native-sdk'; type ButtonPropTypes = Omit & { title: string; @@ -42,27 +46,34 @@ export const Button = ({ }; const useStyles = () => { - const { theme } = useTheme(); + let appTheme: Theme; + try { + /* eslint-disable react-hooks/rules-of-hooks */ + appTheme = useTheme()?.theme; + } catch (e) { + appTheme = defaultTheme; + } + return useMemo( () => StyleSheet.create({ button: { - backgroundColor: theme.colors.primary, + backgroundColor: appTheme.colors.primary, justifyContent: 'center', borderRadius: 8, height: BUTTON_HEIGHT, - paddingHorizontal: theme.variants.spacingSizes.md, + paddingHorizontal: appTheme.variants.spacingSizes.md, }, buttonText: { - color: theme.colors.static_white, - fontWeight: theme.typefaces.heading6.fontWeight, + color: appTheme.colors.static_white, + fontWeight: appTheme.typefaces.heading6.fontWeight, textAlign: 'center', fontSize: 17, }, disabledButtonStyle: { - backgroundColor: theme.colors.disabled, + backgroundColor: appTheme.colors.disabled, }, }), - [theme], + [appTheme], ); }; diff --git a/sample-apps/react-native/dogfood/src/components/CallControlls/CallControlsComponent.tsx b/sample-apps/react-native/dogfood/src/components/CallControlls/BottomControls.tsx similarity index 57% rename from sample-apps/react-native/dogfood/src/components/CallControlls/CallControlsComponent.tsx rename to sample-apps/react-native/dogfood/src/components/CallControlls/BottomControls.tsx index add4173789..9adc2e2168 100644 --- a/sample-apps/react-native/dogfood/src/components/CallControlls/CallControlsComponent.tsx +++ b/sample-apps/react-native/dogfood/src/components/CallControlls/BottomControls.tsx @@ -3,8 +3,9 @@ import { ToggleAudioPublishingButton, ToggleVideoPublishingButton, useCallStateHooks, + useTheme, } from '@stream-io/video-react-native-sdk'; -import React from 'react'; +import React, { useMemo } from 'react'; import { StyleSheet, Text, View } from 'react-native'; import { appTheme } from '../../theme'; import { Z_INDEX } from '../../constants'; @@ -14,7 +15,7 @@ import { ChatButton } from './ChatButton'; import { RecordCallButton } from './RecordCallButton'; import { AudioButton } from './AudioButton'; -export type CallControlsComponentProps = Pick< +export type BottomControlsProps = Pick< CallContentProps, 'supportedReactions' > & { @@ -27,9 +28,10 @@ export const CallControlsComponent = ({ onChatOpenHandler, unreadCountIndicator, onParticipantInfoPress, -}: CallControlsComponentProps) => { +}: BottomControlsProps) => { const { useMicrophoneState } = useCallStateHooks(); const { isSpeakingWhileMuted } = useMicrophoneState(); + const styles = useStyles(); return ( @@ -58,38 +60,46 @@ export const CallControlsComponent = ({ ); }; -const styles = StyleSheet.create({ - speakingLabelContainer: { - backgroundColor: appTheme.colors.static_overlay, - paddingVertical: 10, - width: '100%', - }, - label: { - textAlign: 'center', - color: appTheme.colors.static_white, - }, - callControlsWrapper: { - display: 'flex', - flexDirection: 'row', - justifyContent: 'flex-start', - zIndex: Z_INDEX.IN_FRONT, - }, - container: { - paddingVertical: 16, - paddingHorizontal: 16, - backgroundColor: 'black', - height: 76, - }, - left: { - flex: 2.5, - flexDirection: 'row', - alignItems: 'flex-start', - gap: 6, - }, - right: { - flex: 1, - flexDirection: 'row', - justifyContent: 'flex-end', - gap: 6, - }, -}); +const useStyles = () => { + const { theme } = useTheme(); + + return useMemo( + () => + StyleSheet.create({ + speakingLabelContainer: { + backgroundColor: appTheme.colors.static_overlay, + // paddingVertical: 10, + width: '100%', + }, + label: { + textAlign: 'center', + color: appTheme.colors.static_white, + }, + callControlsWrapper: { + display: 'flex', + flexDirection: 'row', + justifyContent: 'flex-start', + zIndex: Z_INDEX.IN_FRONT, + }, + container: { + paddingVertical: theme.variants.spacingSizes.md, + paddingHorizontal: theme.variants.spacingSizes.md, + backgroundColor: theme.colors.sheetPrimary, + height: 76, + }, + left: { + flex: 2.5, + flexDirection: 'row', + alignItems: 'flex-start', + gap: theme.variants.spacingSizes.xs, + }, + right: { + flex: 1, + flexDirection: 'row', + justifyContent: 'flex-end', + gap: theme.variants.spacingSizes.xs, + }, + }), + [theme], + ); +}; diff --git a/sample-apps/react-native/dogfood/src/components/CallControlls/CallStatusBadge.tsx b/sample-apps/react-native/dogfood/src/components/CallControlls/CallStatusBadge.tsx new file mode 100644 index 0000000000..7698b8f397 --- /dev/null +++ b/sample-apps/react-native/dogfood/src/components/CallControlls/CallStatusBadge.tsx @@ -0,0 +1,105 @@ +import React, { useEffect, useMemo, useState } from 'react'; +import { View, Text, StyleSheet } from 'react-native'; +import { CallDuration } from '../../assets/CallDuration'; +import { RecordCall } from '@stream-io/video-react-native-sdk/src/icons/RecordCall'; +import { IconWrapper } from '@stream-io/video-react-native-sdk/src/icons'; +import { useTheme } from '@stream-io/video-react-native-sdk'; + +/** + * Props for the CallStatusBadge component. + */ +interface CallStatusBadgeProps { + /** + * Indicates if the call is currently being recorded. + * When true, it shows "Recording in progress..." and a specific icon. + * When false, it shows the elapsed time. + */ + isCallRecorded: boolean; +} + +/** + * CallStatusBadge component to display the current status of a call. + * It shows either a recording message or the elapsed time, with an accompanying icon. + * + * @param {CallStatusBadgeProps} props - The props for the component. + */ +export const CallStatusBadge: React.FC = ({ + isCallRecorded, +}) => { + const { + theme: { + colors, + variants: { iconSizes }, + }, + } = useTheme(); + + // TODO: replace this with useDuration when that https://github.com/GetStream/stream-video-js/pull/1528 is merged + const [elapsedSeconds, setElapsedSeconds] = useState(0); + useEffect(() => { + const startedAt = new Date().getTime(); + setElapsedSeconds(Math.floor((Date.now() - startedAt) / 1000)); + const intervalId = setInterval(() => { + setElapsedSeconds((prevSeconds) => prevSeconds + 1); + }, 1000); + return () => clearInterval(intervalId); + }, []); + + const styles = useStyles(isCallRecorded); + + // Format duration to MM:SS + const minutes = Math.floor(elapsedSeconds / 60) + .toString() + .padStart(2, '0'); + const seconds = (elapsedSeconds % 60).toString().padStart(2, '0'); + const timestamp = `${minutes}:${seconds}`; + const text = isCallRecorded ? 'Recording in progress...' : timestamp; + + const icon = isCallRecorded ? ( + + ) : ( + + ); + + return ( + + + {icon} + + {text} + + ); +}; + +const useStyles = (isCallRecorded: boolean) => { + const { theme } = useTheme(); + + return useMemo( + () => + StyleSheet.create({ + container: { + backgroundColor: theme.colors.buttonSecondaryDefault, + borderRadius: 8, + flexDirection: 'row', + height: 36, + paddingLeft: 17, + paddingRight: 5, + justifyContent: 'center', + alignItems: 'center', + width: isCallRecorded ? 200 : 80, + }, + text: { + color: theme.colors.typePrimary, + fontSize: 14, + fontWeight: '600', + flexShrink: 0, + marginLeft: 10, + minWidth: 41, + }, + icon: { + marginTop: 2, + marginRight: 5, + }, + }), + [theme, isCallRecorded], + ); +}; diff --git a/sample-apps/react-native/dogfood/src/components/CallControlls/LayoutSwitcherButton.tsx b/sample-apps/react-native/dogfood/src/components/CallControlls/LayoutSwitcherButton.tsx new file mode 100644 index 0000000000..05f1324a16 --- /dev/null +++ b/sample-apps/react-native/dogfood/src/components/CallControlls/LayoutSwitcherButton.tsx @@ -0,0 +1,48 @@ +import React, { useState } from 'react'; +import { Grid } from '@stream-io/video-react-native-sdk/src/icons/Grid'; +import { + CallControlsButton, + useTheme, +} from '@stream-io/video-react-native-sdk'; +import { IconWrapper } from '@stream-io/video-react-native-sdk/src/icons'; + +export type LayoutSwitcherButtonProps = { + /** + * Handler to be called when the layout switcher button is pressed. + * @returns void + */ + onPressHandler?: () => void; +}; + +/** + * The layout switcher Button can be used to switch different layout arrangements + * of the call participants. + */ +export const LayoutSwitcherButton = ({ + onPressHandler, +}: LayoutSwitcherButtonProps) => { + const { + theme: { colors, defaults, variants }, + } = useTheme(); + const [toggleLayoutMenu, setToggleLayoutMenu] = useState(false); + const buttonColor = toggleLayoutMenu + ? colors.iconPrimaryAccent + : colors.iconPrimaryDefault; + + return ( + { + if (onPressHandler) { + onPressHandler(); + } + setToggleLayoutMenu(!toggleLayoutMenu); + }} + color={colors.sheetPrimary} + > + + + + + ); +}; diff --git a/sample-apps/react-native/dogfood/src/components/CallControlls/RecordCallButton.tsx b/sample-apps/react-native/dogfood/src/components/CallControlls/RecordCallButton.tsx index 7f80e3e406..a3484758a2 100644 --- a/sample-apps/react-native/dogfood/src/components/CallControlls/RecordCallButton.tsx +++ b/sample-apps/react-native/dogfood/src/components/CallControlls/RecordCallButton.tsx @@ -3,7 +3,7 @@ import { CallControlsButton, useTheme, } from '@stream-io/video-react-native-sdk'; -import RecordCall from '../../assets/RecordCall'; +import { RecordCall } from '@stream-io/video-react-native-sdk/src/icons/RecordCall'; import { IconWrapper } from '@stream-io/video-react-native-sdk/src/icons'; /** @@ -23,7 +23,7 @@ export type RecordCallButtonProps = { */ export const RecordCallButton = ({ onPressHandler }: RecordCallButtonProps) => { const { - theme: { colors, recordCallButton, defaults, variants }, + theme: { colors, recordCallButton, variants }, } = useTheme(); const [isRecording, setIsRecording] = useState(false); const buttonColor = isRecording @@ -46,7 +46,7 @@ export const RecordCallButton = ({ onPressHandler }: RecordCallButtonProps) => { diff --git a/sample-apps/react-native/dogfood/src/components/CallControlls/TopControls.tsx b/sample-apps/react-native/dogfood/src/components/CallControlls/TopControls.tsx new file mode 100644 index 0000000000..105bd0a5cf --- /dev/null +++ b/sample-apps/react-native/dogfood/src/components/CallControlls/TopControls.tsx @@ -0,0 +1,95 @@ +import React, { useState, useMemo } from 'react'; +import { View, StyleSheet } from 'react-native'; +import { TopViewBackground } from '@stream-io/video-react-native-sdk/src/icons'; +import { + HangUpCallButton, + useTheme, + ToggleCameraFaceButton, +} from '@stream-io/video-react-native-sdk'; +import { CallStatusBadge } from './CallStatusBadge'; +import { VideoEffectsButton } from '../VideoEffectsButton'; +import { LayoutSwitcherButton } from './LayoutSwitcherButton'; + +export type TopControlsProps = { + /** + * Handler to be called when the hangup button is pressed in the TopControls. + * @returns void + */ + onHangupCallHandler?: () => void; +}; + +export const TopControls = ({ onHangupCallHandler }: TopControlsProps) => { + const [topControlsHeight, setTopControlsHeight] = useState(0); + const [topControlsWidth, setTopControlsWidth] = useState(0); + const styles = useStyles(); + + // TODO: replace this with real data implement PBE-5871 [Demo App] Call Recording flow + const [isCallRecorded] = useState(false); + + const onLayout: React.ComponentProps['onLayout'] = (event) => { + const { height, width } = event.nativeEvent.layout; + if (setTopControlsHeight) { + setTopControlsHeight(height); + setTopControlsWidth(width); + } + }; + + return ( + + {/* Component for the background of the TopControls. Since it has a Linear Gradient, an SVG is used to render it. */} + + + + + {}} /> + + {!isCallRecorded && } + + + + + + + + + + + ); +}; + +const useStyles = () => { + const { theme } = useTheme(); + + return useMemo( + () => + StyleSheet.create({ + content: { + position: 'absolute', + backgroundColor: theme.colors.sheetPrimary, + top: 0, + flexDirection: 'row', + paddingVertical: 2, + paddingHorizontal: theme.variants.spacingSizes.md, + alignItems: 'center', + }, + leftElement: { + flex: 1, + alignItems: 'flex-start', + }, + leftContent: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + }, + centerElement: { + flex: 1, + alignItems: 'center', + }, + rightElement: { + flex: 1, + alignItems: 'flex-end', + }, + }), + [theme], + ); +}; diff --git a/sample-apps/react-native/dogfood/src/components/MeetingUI.tsx b/sample-apps/react-native/dogfood/src/components/MeetingUI.tsx index b4e8aede24..b5765d0749 100644 --- a/sample-apps/react-native/dogfood/src/components/MeetingUI.tsx +++ b/sample-apps/react-native/dogfood/src/components/MeetingUI.tsx @@ -131,9 +131,9 @@ export const MeetingUI = ({ callId, navigation, route }: Props) => { return ( ); } diff --git a/sample-apps/react-native/dogfood/src/components/VideoEffectsButton/index.tsx b/sample-apps/react-native/dogfood/src/components/VideoEffectsButton/index.tsx index 528316bcd1..fee172915d 100644 --- a/sample-apps/react-native/dogfood/src/components/VideoEffectsButton/index.tsx +++ b/sample-apps/react-native/dogfood/src/components/VideoEffectsButton/index.tsx @@ -3,9 +3,9 @@ import { useBackgroundFilters, BlurIntensity, BackgroundFiltersProvider, + useTheme, } from '@stream-io/video-react-native-sdk'; import React, { useState } from 'react'; -import { AutoAwesome } from '../../assets/AutoAwesome'; import { Image, Modal, @@ -18,6 +18,8 @@ import { import { appTheme } from '../../theme'; import { Button } from '../Button'; import { useCustomVideoFilters } from './CustomFilters'; +import { IconWrapper } from '@stream-io/video-react-native-sdk/src/icons'; +import { Effects } from '@stream-io/video-react-native-sdk/src/icons/Effects'; type ImageSourceType = ImageURISource | number; @@ -42,6 +44,7 @@ export const VideoEffectsButton = () => ( const FilterButton = () => { const [modalVisible, setModalVisible] = useState(false); const closeModal = () => setModalVisible(false); + const { theme } = useTheme(); const { disableCustomFilter } = useCustomVideoFilters(); const { isSupported, disableAllFilters } = useBackgroundFilters(); @@ -75,8 +78,17 @@ const FilterButton = () => { - setModalVisible((prev) => !prev)}> - + setModalVisible((prev) => !prev)} + > + + + ); diff --git a/sample-apps/react/messenger-clone/src/components/ChannelHeader/ChannelHeader.tsx b/sample-apps/react/messenger-clone/src/components/ChannelHeader/ChannelHeader.tsx index c6085ab2df..7afbca6bae 100644 --- a/sample-apps/react/messenger-clone/src/components/ChannelHeader/ChannelHeader.tsx +++ b/sample-apps/react/messenger-clone/src/components/ChannelHeader/ChannelHeader.tsx @@ -44,10 +44,7 @@ const UnMemoizedChannelHeader = (props: ChannelHeaderProps) => { > - +

{displayTitle}{' '} diff --git a/sample-apps/react/messenger-clone/src/components/QuickDial/QuickDial.tsx b/sample-apps/react/messenger-clone/src/components/QuickDial/QuickDial.tsx index 11c04d7128..47e6527b6e 100644 --- a/sample-apps/react/messenger-clone/src/components/QuickDial/QuickDial.tsx +++ b/sample-apps/react/messenger-clone/src/components/QuickDial/QuickDial.tsx @@ -120,11 +120,7 @@ const QuickDialButton = ({ away: !user.online, })} > - + ); }; From d87eb42d16a487fbebd53bd828febec71c1b3597 Mon Sep 17 00:00:00 2001 From: Kristian Date: Fri, 1 Nov 2024 14:59:44 +0100 Subject: [PATCH 04/35] feat(design-v2): new layouts (#1529) This PR: - Adds layout switcher modal component. - Fixes some safe area issues in the dogfood app. - Introduces borderRadius sizes in the sdk theme object. --- .../Call/CallContent/CallContent.tsx | 2 +- .../CallControls/ToggleCameraFaceButton.tsx | 4 +- .../CallLayout/CallParticipantsSpotlight.tsx | 53 +++--- .../src/components/Call/Lobby/Lobby.tsx | 111 +++++++------ .../ParticipantView/ParticipantLabel.tsx | 13 +- .../ParticipantView/ParticipantView.tsx | 14 +- .../src/icons/CameraSwitch.tsx | 2 +- .../react-native-sdk/src/icons/Effects.tsx | 2 +- packages/react-native-sdk/src/theme/theme.ts | 8 + .../react-native/dogfood/src/assets/Grid.tsx | 17 ++ .../dogfood/src/assets/Spotlight.tsx | 17 ++ .../dogfood/src/components/ActiveCall.tsx | 22 ++- .../CallControlls/BottomControls.tsx | 19 +-- .../CallControlls/LayoutSwitcherButton.tsx | 51 +++++- .../CallControlls/LayoutSwitcherModal.tsx | 155 ++++++++++++++++++ .../components/CallControlls/TopControls.tsx | 3 +- .../dogfood/src/components/MeetingUI.tsx | 15 +- .../components/ParticipantsLayoutButton.tsx | 134 --------------- .../components/VideoEffectsButton/index.tsx | 2 +- .../dogfood/src/contexts/LayoutContext.tsx | 44 +++++ .../src/screens/Meeting/JoinMeetingScreen.tsx | 114 +++++++------ 21 files changed, 499 insertions(+), 303 deletions(-) create mode 100644 sample-apps/react-native/dogfood/src/assets/Grid.tsx create mode 100644 sample-apps/react-native/dogfood/src/assets/Spotlight.tsx create mode 100644 sample-apps/react-native/dogfood/src/components/CallControlls/LayoutSwitcherModal.tsx delete mode 100644 sample-apps/react-native/dogfood/src/components/ParticipantsLayoutButton.tsx create mode 100644 sample-apps/react-native/dogfood/src/contexts/LayoutContext.tsx diff --git a/packages/react-native-sdk/src/components/Call/CallContent/CallContent.tsx b/packages/react-native-sdk/src/components/Call/CallContent/CallContent.tsx index 0ec66f8df2..cf2e591efc 100644 --- a/packages/react-native-sdk/src/components/Call/CallContent/CallContent.tsx +++ b/packages/react-native-sdk/src/components/Call/CallContent/CallContent.tsx @@ -197,7 +197,7 @@ export const CallContent = ({ /> )} - + {!isInPiPMode && CallTopView && ( )} diff --git a/packages/react-native-sdk/src/components/Call/CallControls/ToggleCameraFaceButton.tsx b/packages/react-native-sdk/src/components/Call/CallControls/ToggleCameraFaceButton.tsx index ac27479f69..10e85a0e0a 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/ToggleCameraFaceButton.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/ToggleCameraFaceButton.tsx @@ -28,7 +28,7 @@ export const ToggleCameraFaceButton = ({ const isVideoEnabledInCall = callSettings?.video.enabled; const { - theme: { colors, toggleCameraFaceButton, defaults }, + theme: { colors, toggleCameraFaceButton, variants }, } = useTheme(); const onPress = async () => { if (onPressHandler) { @@ -54,7 +54,7 @@ export const ToggleCameraFaceButton = ({ > { const { - theme: { colors, callParticipantsSpotlight }, + theme: { callParticipantsSpotlight, variants }, } = useTheme(); + const styles = useStyles(); const { useParticipants } = useCallStateHooks(); const _allParticipants = useParticipants({ sortBy: speakerLayoutSortPreset, @@ -88,7 +89,7 @@ export const CallParticipantsSpotlight = ({ }; const spotlightContainerLandscapeStyles: ViewStyle = { - marginHorizontal: landscape ? 0 : 8, + marginHorizontal: landscape ? 0 : variants.spacingSizes.xs, }; return ( @@ -97,9 +98,6 @@ export const CallParticipantsSpotlight = ({ style={[ styles.container, landscapeStyles, - { - backgroundColor: colors.background2, - }, callParticipantsSpotlight.container, ]} > @@ -155,20 +153,29 @@ export const CallParticipantsSpotlight = ({ ); }; -const styles = StyleSheet.create({ - container: { - flex: 1, - }, - fullScreenSpotlightContainer: { - flex: 1, - }, - spotlightContainer: { - flex: 2, - overflow: 'hidden', - borderRadius: 10, - marginHorizontal: 8, - }, - callParticipantsListContainer: { - flex: 1, - }, -}); +const useStyles = () => { + const { theme } = useTheme(); + return useMemo( + () => + StyleSheet.create({ + container: { + flex: 1, + padding: theme.variants.spacingSizes.xs, + backgroundColor: theme.colors.sheetPrimary, + }, + fullScreenSpotlightContainer: { + flex: 1, + }, + spotlightContainer: { + flex: 2, + overflow: 'hidden', + borderRadius: theme.variants.borderRadiusSizes.sm, + marginHorizontal: theme.variants.spacingSizes.sm, + }, + callParticipantsListContainer: { + flex: 1, + }, + }), + [theme] + ); +}; diff --git a/packages/react-native-sdk/src/components/Call/Lobby/Lobby.tsx b/packages/react-native-sdk/src/components/Call/Lobby/Lobby.tsx index 23db831fba..e4f59c65bf 100644 --- a/packages/react-native-sdk/src/components/Call/Lobby/Lobby.tsx +++ b/packages/react-native-sdk/src/components/Call/Lobby/Lobby.tsx @@ -1,4 +1,4 @@ -import React, { ComponentType } from 'react'; +import React, { ComponentType, useMemo } from 'react'; import { StyleSheet, Text, View, ViewStyle } from 'react-native'; import { useCallStateHooks, @@ -63,6 +63,7 @@ export const Lobby = ({ const { theme: { colors, lobby, typefaces }, } = useTheme(); + const styles = useStyles(); const connectedUser = useConnectedUser(); const { useCameraState, useCallSettings } = useCallStateHooks(); const callSettings = useCallSettings(); @@ -159,6 +160,7 @@ const ParticipantStatus = () => { const { theme: { colors, typefaces, lobby }, } = useTheme(); + const styles = useStyles(); const connectedUser = useConnectedUser(); const participantLabel = connectedUser?.name ?? connectedUser?.id; return ( @@ -186,51 +188,62 @@ const ParticipantStatus = () => { ); }; -const styles = StyleSheet.create({ - container: { - flex: 1, - justifyContent: 'space-evenly', - }, - topContainer: { - flex: 2, - justifyContent: 'space-evenly', - paddingHorizontal: 12, - }, - heading: { - textAlign: 'center', - }, - subHeading: { - textAlign: 'center', - }, - videoContainer: { - height: LOBBY_VIDEO_VIEW_HEIGHT, - borderRadius: 20, - justifyContent: 'space-between', - alignItems: 'center', - overflow: 'hidden', - padding: 8, - }, - topView: {}, - bottomContainer: { - flex: 2, - justifyContent: 'space-evenly', - paddingHorizontal: 12, - }, - participantStatusContainer: { - alignSelf: 'flex-start', - flexDirection: 'row', - alignItems: 'center', - padding: 8, - borderRadius: 5, - }, - avatarContainer: { - flex: 2, - justifyContent: 'center', - }, - userNameLabel: { - flexShrink: 1, - }, - audioMutedIconContainer: { - marginLeft: 8, - }, -}); +const useStyles = () => { + const { theme } = useTheme(); + return useMemo( + () => + StyleSheet.create({ + container: { + flex: 1, + justifyContent: 'space-evenly', + paddingRight: theme.variants.insets.right, + paddingLeft: theme.variants.insets.left, + paddingTop: theme.variants.insets.top, + paddingBottom: theme.variants.insets.bottom, + }, + topContainer: { + flex: 2, + justifyContent: 'space-evenly', + paddingHorizontal: 12, + }, + heading: { + textAlign: 'center', + }, + subHeading: { + textAlign: 'center', + }, + videoContainer: { + height: LOBBY_VIDEO_VIEW_HEIGHT, + borderRadius: 20, + justifyContent: 'space-between', + alignItems: 'center', + overflow: 'hidden', + padding: 8, + }, + topView: {}, + bottomContainer: { + flex: 2, + justifyContent: 'space-evenly', + paddingHorizontal: 12, + }, + participantStatusContainer: { + alignSelf: 'flex-start', + flexDirection: 'row', + alignItems: 'center', + padding: 8, + borderRadius: 5, + }, + avatarContainer: { + flex: 2, + justifyContent: 'center', + }, + userNameLabel: { + flexShrink: 1, + }, + audioMutedIconContainer: { + marginLeft: 8, + }, + }), + [theme] + ); +}; diff --git a/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantLabel.tsx b/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantLabel.tsx index 5d4ee2ad81..a226b41b1b 100644 --- a/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantLabel.tsx +++ b/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantLabel.tsx @@ -97,15 +97,7 @@ export const ParticipantLabel = ({ ]} > - + {participantLabel} @@ -152,6 +144,9 @@ const useStyles = () => { userNameLabel: { flexShrink: 1, marginTop: 2, + fontSize: 13, + fontWeight: '400', + color: theme.colors.iconPrimaryDefault, }, screenShareIconContainer: { marginRight: theme.variants.spacingSizes.sm, diff --git a/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantView.tsx b/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantView.tsx index 76b6e74921..758dd7538b 100644 --- a/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantView.tsx +++ b/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantView.tsx @@ -149,7 +149,13 @@ export const ParticipantView = ({ videoZOrder={videoZOrder} /> )} - + {ParticipantLabel && ( )} @@ -169,10 +175,7 @@ const useStyles = () => { container: { justifyContent: 'space-between', overflow: 'hidden', - borderWidth: 2, - borderColor: 'transparent', - margin: theme.variants.spacingSizes.sm, - borderRadius: 16, + borderRadius: theme.variants.borderRadiusSizes.md, }, footerContainer: { flexDirection: 'row', @@ -182,6 +185,7 @@ const useStyles = () => { highligtedContainer: { borderWidth: 2, }, + networkIndicatorOnly: { justifyContent: 'flex-end' }, }), [theme] ); diff --git a/packages/react-native-sdk/src/icons/CameraSwitch.tsx b/packages/react-native-sdk/src/icons/CameraSwitch.tsx index a4fc8aa5f9..62bb662cd2 100644 --- a/packages/react-native-sdk/src/icons/CameraSwitch.tsx +++ b/packages/react-native-sdk/src/icons/CameraSwitch.tsx @@ -8,7 +8,7 @@ type Props = { }; export const CameraSwitch = ({ color, size }: Props) => ( - + ( - + ; @@ -298,6 +299,13 @@ export const defaultTheme: Theme = { lg: 44, xl: 56, }, + borderRadiusSizes: { + xs: 4, + sm: 8, + md: 16, + lg: 24, + xl: 32, + }, buttonSizes: { xs: 40, sm: 50, diff --git a/sample-apps/react-native/dogfood/src/assets/Grid.tsx b/sample-apps/react-native/dogfood/src/assets/Grid.tsx new file mode 100644 index 0000000000..6b6e09b8b8 --- /dev/null +++ b/sample-apps/react-native/dogfood/src/assets/Grid.tsx @@ -0,0 +1,17 @@ +import React from 'react'; +import { Svg, Path } from 'react-native-svg'; +import { ColorValue } from 'react-native/types'; + +type Props = { + color: ColorValue; + size: number; +}; + +export const Grid = ({ color, size }: Props) => ( + + + +); diff --git a/sample-apps/react-native/dogfood/src/assets/Spotlight.tsx b/sample-apps/react-native/dogfood/src/assets/Spotlight.tsx new file mode 100644 index 0000000000..a360b5edcd --- /dev/null +++ b/sample-apps/react-native/dogfood/src/assets/Spotlight.tsx @@ -0,0 +1,17 @@ +import React from 'react'; +import { Svg, Path } from 'react-native-svg'; +import { ColorValue } from 'react-native/types'; + +type Props = { + color: ColorValue; + size: number; +}; + +export const SpotLight = ({ color, size }: Props) => ( + + + +); diff --git a/sample-apps/react-native/dogfood/src/components/ActiveCall.tsx b/sample-apps/react-native/dogfood/src/components/ActiveCall.tsx index 0ed9194ab4..b5a17452d7 100644 --- a/sample-apps/react-native/dogfood/src/components/ActiveCall.tsx +++ b/sample-apps/react-native/dogfood/src/components/ActiveCall.tsx @@ -14,6 +14,7 @@ import { import { useOrientation } from '../hooks/useOrientation'; import { Z_INDEX } from '../constants'; import { TopControls } from './CallControlls/TopControls'; +import { useLayout } from '../contexts/LayoutContext'; type ActiveCallProps = BottomControlsProps & { onHangupCallHandler?: () => void; @@ -32,6 +33,7 @@ export const ActiveCall = ({ const currentOrientation = useOrientation(); const styles = useStyles(); const { theme: colors } = useTheme(); + const { selectedLayout } = useLayout(); const onOpenCallParticipantsInfo = useCallback(() => { setIsCallParticipantsVisible(true); @@ -64,12 +66,15 @@ export const ActiveCall = ({ backgroundColor={colors.sheetPrimary} /> + + { const { theme } = useTheme(); - return useMemo( () => StyleSheet.create({ @@ -107,6 +111,22 @@ const useStyles = () => { height: theme.variants.insets.bottom, backgroundColor: theme.colors.sheetPrimary, }, + leftUnsafeArea: { + position: 'absolute', + top: 0, + bottom: 0, + left: 0, + width: theme.variants.insets.left, + backgroundColor: theme.colors.sheetPrimary, + }, + rightUnsafeArea: { + position: 'absolute', + top: 0, + bottom: 0, + right: 0, + width: theme.variants.insets.right, + backgroundColor: theme.colors.sheetPrimary, + }, view: { ...StyleSheet.absoluteFillObject, zIndex: Z_INDEX.IN_FRONT, diff --git a/sample-apps/react-native/dogfood/src/components/CallControlls/BottomControls.tsx b/sample-apps/react-native/dogfood/src/components/CallControlls/BottomControls.tsx index 9adc2e2168..8079d2c233 100644 --- a/sample-apps/react-native/dogfood/src/components/CallControlls/BottomControls.tsx +++ b/sample-apps/react-native/dogfood/src/components/CallControlls/BottomControls.tsx @@ -31,7 +31,7 @@ export const CallControlsComponent = ({ }: BottomControlsProps) => { const { useMicrophoneState } = useCallStateHooks(); const { isSpeakingWhileMuted } = useMicrophoneState(); - const styles = useStyles(); + const styles = useStyles(isSpeakingWhileMuted); return ( @@ -60,15 +60,20 @@ export const CallControlsComponent = ({ ); }; -const useStyles = () => { +const useStyles = (showMicLabel: boolean) => { const { theme } = useTheme(); return useMemo( () => StyleSheet.create({ + container: { + paddingVertical: !showMicLabel ? theme.variants.spacingSizes.md : 0, + paddingHorizontal: theme.variants.spacingSizes.md, + backgroundColor: theme.colors.sheetPrimary, + height: 76, + }, speakingLabelContainer: { backgroundColor: appTheme.colors.static_overlay, - // paddingVertical: 10, width: '100%', }, label: { @@ -81,12 +86,6 @@ const useStyles = () => { justifyContent: 'flex-start', zIndex: Z_INDEX.IN_FRONT, }, - container: { - paddingVertical: theme.variants.spacingSizes.md, - paddingHorizontal: theme.variants.spacingSizes.md, - backgroundColor: theme.colors.sheetPrimary, - height: 76, - }, left: { flex: 2.5, flexDirection: 'row', @@ -100,6 +99,6 @@ const useStyles = () => { gap: theme.variants.spacingSizes.xs, }, }), - [theme], + [theme, showMicLabel], ); }; diff --git a/sample-apps/react-native/dogfood/src/components/CallControlls/LayoutSwitcherButton.tsx b/sample-apps/react-native/dogfood/src/components/CallControlls/LayoutSwitcherButton.tsx index 05f1324a16..e2e9881f7a 100644 --- a/sample-apps/react-native/dogfood/src/components/CallControlls/LayoutSwitcherButton.tsx +++ b/sample-apps/react-native/dogfood/src/components/CallControlls/LayoutSwitcherButton.tsx @@ -1,10 +1,14 @@ import React, { useState } from 'react'; -import { Grid } from '@stream-io/video-react-native-sdk/src/icons/Grid'; import { CallControlsButton, useTheme, } from '@stream-io/video-react-native-sdk'; import { IconWrapper } from '@stream-io/video-react-native-sdk/src/icons'; +import LayoutSwitcherModal from './LayoutSwitcherModal'; +import { ColorValue } from 'react-native'; +import { Grid } from '../../assets/Grid'; +import { SpotLight } from '../../assets/Spotlight'; +import { useLayout } from '../../contexts/LayoutContext'; export type LayoutSwitcherButtonProps = { /** @@ -14,6 +18,17 @@ export type LayoutSwitcherButtonProps = { onPressHandler?: () => void; }; +const getIcon = (selectedButton: string, color: ColorValue, size: number) => { + switch (selectedButton) { + case 'grid': + return ; + case 'spotlight': + return ; + default: + return 'grid'; + } +}; + /** * The layout switcher Button can be used to switch different layout arrangements * of the call participants. @@ -22,27 +37,51 @@ export const LayoutSwitcherButton = ({ onPressHandler, }: LayoutSwitcherButtonProps) => { const { - theme: { colors, defaults, variants }, + theme: { colors, variants }, } = useTheme(); - const [toggleLayoutMenu, setToggleLayoutMenu] = useState(false); - const buttonColor = toggleLayoutMenu + + const { selectedLayout } = useLayout(); + const [isModalVisible, setIsModalVisible] = useState(false); + const [anchorPosition, setAnchorPosition] = useState<{ + x: number; + y: number; + width: number; + height: number; + } | null>(null); + + const buttonColor = isModalVisible ? colors.iconPrimaryAccent : colors.iconPrimaryDefault; + const handleOpenModal = () => setIsModalVisible(true); + const handleCloseModal = () => setIsModalVisible(false); + + const handleLayout = (event: any) => { + const { x, y, width, height } = event.nativeEvent.layout; + setAnchorPosition({ x, y: y + height, width, height }); + }; + return ( { + handleOpenModal(); if (onPressHandler) { onPressHandler(); } - setToggleLayoutMenu(!toggleLayoutMenu); + setIsModalVisible(!isModalVisible); }} color={colors.sheetPrimary} > - + {getIcon(selectedLayout, buttonColor, variants.iconSizes.lg)} + ); }; diff --git a/sample-apps/react-native/dogfood/src/components/CallControlls/LayoutSwitcherModal.tsx b/sample-apps/react-native/dogfood/src/components/CallControlls/LayoutSwitcherModal.tsx new file mode 100644 index 0000000000..cd7744e911 --- /dev/null +++ b/sample-apps/react-native/dogfood/src/components/CallControlls/LayoutSwitcherModal.tsx @@ -0,0 +1,155 @@ +import React, { useEffect, useState, useMemo } from 'react'; +import { + View, + TouchableOpacity, + Text, + StyleSheet, + Dimensions, + Modal, +} from 'react-native'; +import { useTheme } from '@stream-io/video-react-native-sdk'; +import { Grid } from '../../assets/Grid'; +import { SpotLight } from '../../assets/Spotlight'; +import { Layout, useLayout } from '../../contexts/LayoutContext'; + +interface AnchorPosition { + x: number; + y: number; + height: number; +} + +interface PopupComponentProps { + anchorPosition?: AnchorPosition | null; + isVisible: boolean; + onClose: () => void; +} + +const LayoutSwitcherModal: React.FC = ({ + isVisible, + onClose, + anchorPosition, +}) => { + const { theme } = useTheme(); + const styles = useStyles(); + const [popupPosition, setPopupPosition] = useState({ top: 0, left: 0 }); + const { selectedLayout, onLayoutSelection } = useLayout(); + const topInset = theme.variants.insets.top; + const leftInset = theme.variants.insets.left; + + useEffect(() => { + if (isVisible && anchorPosition) { + const windowHeight = Dimensions.get('window').height; + const windowWidth = Dimensions.get('window').width; + + let top = anchorPosition.y + anchorPosition.height / 2 + topInset; + let left = anchorPosition.x + leftInset; + + // Ensure the popup stays within the screen bounds + if (top + 150 > windowHeight) { + top = anchorPosition.y - 150; + } + if (left + 200 > windowWidth) { + left = windowWidth - 200; + } + + setPopupPosition({ top, left }); + } + }, [isVisible, anchorPosition, topInset, leftInset]); + + if (!isVisible || !anchorPosition) { + return null; + } + + const onPressHandler = (layout: Layout) => { + onLayoutSelection(layout); + onClose(); + }; + + return ( + + + + onPressHandler('grid')} + > + + Grid + + onPressHandler('spotlight')} + > + + Spotlight + + + + + ); +}; + +const useStyles = () => { + const { theme } = useTheme(); + + return useMemo( + () => + StyleSheet.create({ + overlay: { + flex: 1, + }, + modal: { + position: 'absolute', + width: 212, + backgroundColor: theme.colors.sheetSecondary, + borderRadius: theme.variants.borderRadiusSizes.lg, + padding: theme.variants.spacingSizes.md, + gap: theme.variants.spacingSizes.sm, + }, + button: { + backgroundColor: theme.colors.buttonSecondaryDefault, + borderRadius: theme.variants.borderRadiusSizes.lg, + flexDirection: 'row', + justifyContent: 'flex-start', + alignItems: 'center', + paddingHorizontal: theme.variants.spacingSizes.md, + paddingVertical: theme.variants.spacingSizes.sm, + }, + selectedButton: { + backgroundColor: theme.colors.primary, + }, + buttonText: { + color: 'white', + textAlign: 'center', + fontWeight: '600', + marginTop: 2, + marginLeft: theme.variants.spacingSizes.xs, + }, + }), + [theme], + ); +}; + +export default LayoutSwitcherModal; diff --git a/sample-apps/react-native/dogfood/src/components/CallControlls/TopControls.tsx b/sample-apps/react-native/dogfood/src/components/CallControlls/TopControls.tsx index 105bd0a5cf..2699eed25b 100644 --- a/sample-apps/react-native/dogfood/src/components/CallControlls/TopControls.tsx +++ b/sample-apps/react-native/dogfood/src/components/CallControlls/TopControls.tsx @@ -41,7 +41,7 @@ export const TopControls = ({ onHangupCallHandler }: TopControlsProps) => { - {}} /> + {!isCallRecorded && } @@ -59,7 +59,6 @@ export const TopControls = ({ onHangupCallHandler }: TopControlsProps) => { const useStyles = () => { const { theme } = useTheme(); - return useMemo( () => StyleSheet.create({ diff --git a/sample-apps/react-native/dogfood/src/components/MeetingUI.tsx b/sample-apps/react-native/dogfood/src/components/MeetingUI.tsx index b5765d0749..1c64338a0c 100644 --- a/sample-apps/react-native/dogfood/src/components/MeetingUI.tsx +++ b/sample-apps/react-native/dogfood/src/components/MeetingUI.tsx @@ -13,6 +13,7 @@ import { useAppGlobalStoreSetState } from '../contexts/AppContext'; import { AuthenticationProgress } from './AuthenticatingProgress'; import { CallErrorComponent } from './CallErrorComponent'; import { useUnreadCount } from '../hooks/useUnreadCount'; +import { LayoutProvider } from '../contexts/LayoutContext'; type Props = NativeStackScreenProps< MeetingStackParamList, @@ -129,12 +130,14 @@ export const MeetingUI = ({ callId, navigation, route }: Props) => { ); } else { return ( - + + + ); } }; diff --git a/sample-apps/react-native/dogfood/src/components/ParticipantsLayoutButton.tsx b/sample-apps/react-native/dogfood/src/components/ParticipantsLayoutButton.tsx deleted file mode 100644 index 982847e71a..0000000000 --- a/sample-apps/react-native/dogfood/src/components/ParticipantsLayoutButton.tsx +++ /dev/null @@ -1,134 +0,0 @@ -import React, { useState } from 'react'; -import { Pressable, Text, Modal, StyleSheet, View } from 'react-native'; -import GridIconSvg from '../assets/GridIconSvg'; -import { appTheme } from '../theme'; - -type Layout = 'grid' | 'spotlight'; - -const LayoutSelectionItem = ({ - layout, - selectedLayout, - setSelectedLayout, - closeModal, -}: { - layout: Layout; - selectedLayout: Layout; - setSelectedLayout: (mode: Layout) => void; - closeModal: () => void; -}) => { - if (!layout) { - return null; - } - - return ( - { - setSelectedLayout(layout); - closeModal(); - }} - style={styles.modalButton} - > - - {layout[0].toUpperCase() + layout.substring(1)} - - - ); -}; - -export const ParticipantsLayoutSwitchButton = ({ - selectedLayout, - setSelectedLayout, -}: { - selectedLayout: Layout; - setSelectedLayout: (m: Layout) => void; -}) => { - const [modalVisible, setModalVisible] = useState(false); - const closeModal = () => setModalVisible(false); - - return ( - <> - - setModalVisible(false)} - > - true}> - - - - - - - setModalVisible(true)} - style={styles.gridButton} - > - - - - - ); -}; - -const styles = StyleSheet.create({ - centeredView: { - flex: 1, - justifyContent: 'center', - alignItems: 'center', - backgroundColor: 'rgba(0, 0, 0, 0.5)', - }, - modalView: { - backgroundColor: appTheme.colors.static_grey, - borderRadius: 20, - padding: appTheme.spacing.md, - alignItems: 'flex-start', - shadowColor: '#000', - shadowOffset: { - width: 0, - height: 2, - }, - shadowOpacity: 0.25, - shadowRadius: 4, - elevation: 5, - }, - gridButton: { - height: 30, - width: 30, - }, - modalButton: { - padding: appTheme.spacing.lg, - }, - modalText: { - fontSize: 20, - fontWeight: 'bold', - }, - buttonsContainer: { - paddingHorizontal: appTheme.spacing.sm, - }, -}); diff --git a/sample-apps/react-native/dogfood/src/components/VideoEffectsButton/index.tsx b/sample-apps/react-native/dogfood/src/components/VideoEffectsButton/index.tsx index fee172915d..05fddd8405 100644 --- a/sample-apps/react-native/dogfood/src/components/VideoEffectsButton/index.tsx +++ b/sample-apps/react-native/dogfood/src/components/VideoEffectsButton/index.tsx @@ -86,7 +86,7 @@ const FilterButton = () => { diff --git a/sample-apps/react-native/dogfood/src/contexts/LayoutContext.tsx b/sample-apps/react-native/dogfood/src/contexts/LayoutContext.tsx new file mode 100644 index 0000000000..05e0134c7a --- /dev/null +++ b/sample-apps/react-native/dogfood/src/contexts/LayoutContext.tsx @@ -0,0 +1,44 @@ +import React, { + createContext, + useContext, + useState, + ReactNode, + useCallback, +} from 'react'; + +export type Layout = 'grid' | 'spotlight'; + +interface LayoutContextState { + selectedLayout: Layout; + onLayoutSelection: (layout: Layout) => void; +} + +const LayoutContext = createContext(null); + +interface LayoutProviderProps { + children: ReactNode; +} + +const LayoutProvider: React.FC = ({ children }) => { + const [selectedLayout, setSelectedLayout] = useState('grid'); + + const onLayoutSelection = useCallback((layout: Layout) => { + setSelectedLayout(layout); + }, []); + + return ( + + {children} + + ); +}; + +const useLayout = (): LayoutContextState => { + const context = useContext(LayoutContext); + if (!context) { + throw new Error('useLayout must be used within a LayoutProvider'); + } + return context; +}; + +export { LayoutProvider, useLayout }; diff --git a/sample-apps/react-native/dogfood/src/screens/Meeting/JoinMeetingScreen.tsx b/sample-apps/react-native/dogfood/src/screens/Meeting/JoinMeetingScreen.tsx index 075359e82e..2587996510 100644 --- a/sample-apps/react-native/dogfood/src/screens/Meeting/JoinMeetingScreen.tsx +++ b/sample-apps/react-native/dogfood/src/screens/Meeting/JoinMeetingScreen.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useState, useMemo } from 'react'; import { Image, KeyboardAvoidingView, @@ -16,7 +16,7 @@ import { appTheme } from '../../theme'; import { TextInput } from '../../components/TextInput'; import { Button } from '../../components/Button'; import { prontoCallId$ } from '../../hooks/useProntoLinkEffect'; -import { useI18n } from '@stream-io/video-react-native-sdk'; +import { useI18n, useTheme } from '@stream-io/video-react-native-sdk'; import { useOrientation } from '../../hooks/useOrientation'; type JoinMeetingScreenProps = NativeStackScreenProps< @@ -29,6 +29,7 @@ const JoinMeetingScreen = (props: JoinMeetingScreenProps) => { const [linking, setLinking] = useState(false); const { t } = useI18n(); const orientation = useOrientation(); + const styles = useStyles(); const { navigation } = props; const userImageUrl = useAppGlobalStoreValue((store) => store.userImageUrl); @@ -118,55 +119,64 @@ const JoinMeetingScreen = (props: JoinMeetingScreenProps) => { ); }; -const styles = StyleSheet.create({ - container: { - padding: appTheme.spacing.lg, - backgroundColor: appTheme.colors.static_grey, - flex: 1, - justifyContent: 'space-evenly', - }, - topContainer: { - flex: 1, - justifyContent: 'center', - }, - logo: { - height: 100, - width: 100, - borderRadius: 50, - alignSelf: 'center', - }, - title: { - fontSize: 30, - color: appTheme.colors.static_white, - fontWeight: '500', - textAlign: 'center', - marginTop: appTheme.spacing.lg, - }, - subTitle: { - color: appTheme.colors.light_gray, - fontSize: 16, - textAlign: 'center', - marginHorizontal: appTheme.spacing.xl, - }, - bottomContainer: { - flex: 1, - justifyContent: 'center', - }, - joinCallButton: { - marginLeft: appTheme.spacing.lg, - }, - startNewCallButton: { - width: '100%', - }, - iconButton: { - width: 40, - }, - createCall: { - display: 'flex', - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'space-between', - }, -}); +const useStyles = () => { + const { theme } = useTheme(); + return useMemo( + () => + StyleSheet.create({ + container: { + padding: appTheme.spacing.lg, + backgroundColor: appTheme.colors.static_grey, + flex: 1, + justifyContent: 'space-evenly', + paddingRight: theme.variants.insets.right, + paddingLeft: theme.variants.insets.left, + }, + topContainer: { + flex: 1, + justifyContent: 'center', + }, + logo: { + height: 100, + width: 100, + borderRadius: 50, + alignSelf: 'center', + }, + title: { + fontSize: 30, + color: appTheme.colors.static_white, + fontWeight: '500', + textAlign: 'center', + marginTop: appTheme.spacing.lg, + }, + subTitle: { + color: appTheme.colors.light_gray, + fontSize: 16, + textAlign: 'center', + marginHorizontal: appTheme.spacing.xl, + }, + bottomContainer: { + flex: 1, + justifyContent: 'center', + }, + joinCallButton: { + marginLeft: appTheme.spacing.lg, + }, + startNewCallButton: { + width: '100%', + }, + iconButton: { + width: 40, + }, + createCall: { + display: 'flex', + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + }, + }), + [theme], + ); +}; export default JoinMeetingScreen; From 0235d952a466553d0277824c8121219995dbc7da Mon Sep 17 00:00:00 2001 From: Santhosh Vaiyapuri <3846977+santhoshvai@users.noreply.github.com> Date: Fri, 1 Nov 2024 12:11:58 +0100 Subject: [PATCH 05/35] fix: camera not enabled on foreground notifications (#1546) --- .../src/devices/InputMediaDeviceManager.ts | 6 ++--- .../__tests__/InputMediaDeviceManager.test.ts | 23 +++++++++++++++++++ packages/react-native-sdk/package.json | 1 + .../src/contexts/ThemeContext.tsx | 2 +- .../src/providers/StreamCall.tsx | 12 ++++++++-- .../react-native/dogfood/ios/Podfile.lock | 4 ++-- yarn.lock | 1 + 7 files changed, 41 insertions(+), 8 deletions(-) diff --git a/packages/client/src/devices/InputMediaDeviceManager.ts b/packages/client/src/devices/InputMediaDeviceManager.ts index a5cda2df78..ad31d160e9 100644 --- a/packages/client/src/devices/InputMediaDeviceManager.ts +++ b/packages/client/src/devices/InputMediaDeviceManager.ts @@ -74,10 +74,10 @@ export abstract class InputMediaDeviceManager< * Starts stream. */ async enable() { + this.state.prevStatus = this.state.optimisticStatus; if (this.state.optimisticStatus === 'enabled') { return; } - this.state.setPendingStatus('enabled'); await withCancellation(this.statusChangeConcurrencyTag, async (signal) => { @@ -97,7 +97,7 @@ export abstract class InputMediaDeviceManager< * @param {boolean} [forceStop=false] when true, stops the tracks regardless of the state.disableMode */ async disable(forceStop: boolean = false) { - this.state.prevStatus = this.state.status; + this.state.prevStatus = this.state.optimisticStatus; if (!forceStop && this.state.optimisticStatus === 'disabled') { return; } @@ -131,7 +131,7 @@ export abstract class InputMediaDeviceManager< async resume() { if ( this.state.prevStatus === 'enabled' && - this.state.status === 'disabled' + this.state.status !== 'enabled' ) { await this.enable(); } diff --git a/packages/client/src/devices/__tests__/InputMediaDeviceManager.test.ts b/packages/client/src/devices/__tests__/InputMediaDeviceManager.test.ts index 545bb1902e..3d147feee4 100644 --- a/packages/client/src/devices/__tests__/InputMediaDeviceManager.test.ts +++ b/packages/client/src/devices/__tests__/InputMediaDeviceManager.test.ts @@ -241,6 +241,29 @@ describe('InputMediaDeviceManager.test', () => { expect(manager.enable).toHaveBeenCalledOnce(); }); + it(`should resume if enable was cancelled due to disable call`, async () => { + vi.spyOn(manager, 'enable'); + + manager.enable(); + + expect(manager.enable).toHaveBeenCalledOnce(); + + // enable was not awaited so cancelled by disabled + await manager.disable(); + + manager.resume(); + + expect(manager.enable).toBeCalledTimes(2); + + // this disable is not awaited, but will cancel the enable anyway + // so resume must work here too + manager.disable(); + + manager.resume(); + + expect(manager.enable).toBeCalledTimes(3); + }); + it('should provide default constraints to `getStream` method', () => { manager.setDefaultConstraints({ echoCancellation: true, diff --git a/packages/react-native-sdk/package.json b/packages/react-native-sdk/package.json index 445ec1b162..c9c8bbb6e3 100644 --- a/packages/react-native-sdk/package.json +++ b/packages/react-native-sdk/package.json @@ -51,6 +51,7 @@ "intl-pluralrules": "2.0.1", "lodash.merge": "^4.6.2", "react-native-url-polyfill": "1.3.0", + "rxjs": "~7.8.1", "text-encoding-polyfill": "0.6.7" }, "peerDependencies": { diff --git a/packages/react-native-sdk/src/contexts/ThemeContext.tsx b/packages/react-native-sdk/src/contexts/ThemeContext.tsx index c2583b3d53..e3da09dd94 100644 --- a/packages/react-native-sdk/src/contexts/ThemeContext.tsx +++ b/packages/react-native-sdk/src/contexts/ThemeContext.tsx @@ -5,7 +5,7 @@ import React, { useMemo, } from 'react'; -import merge from 'lodash/merge'; +import merge from 'lodash.merge'; import { defaultTheme, Theme } from '../theme/theme'; diff --git a/packages/react-native-sdk/src/providers/StreamCall.tsx b/packages/react-native-sdk/src/providers/StreamCall.tsx index 152e0a8907..b5072f5f55 100644 --- a/packages/react-native-sdk/src/providers/StreamCall.tsx +++ b/packages/react-native-sdk/src/providers/StreamCall.tsx @@ -71,13 +71,21 @@ const AppStateListener = () => { // in Android, we need to check if we are in PiP mode // in PiP mode, we don't want to disable the camera NativeModules?.StreamVideoReactNative?.isInPiPMode().then( - async (isInPiP: boolean | null | undefined) => { + (isInPiP: boolean | null | undefined) => { if (!isInPiP) { - await call?.camera?.disable(); + const currentState = appState.current; + if (currentState === 'active') { + // this is to handle the case that the app became active as soon as it went to background + // in this case, we dont want to disable the camera + // this happens on foreground push notifications + return; + } + call?.camera?.disable(); } } ); } else { + // shouldDisableIOSLocalVideoOnBackgroundRef is false, if local video is enabled on PiP if (shouldDisableIOSLocalVideoOnBackgroundRef.current) { call?.camera?.disable(); } diff --git a/sample-apps/react-native/dogfood/ios/Podfile.lock b/sample-apps/react-native/dogfood/ios/Podfile.lock index dcd202c2c3..35f9915e76 100644 --- a/sample-apps/react-native/dogfood/ios/Podfile.lock +++ b/sample-apps/react-native/dogfood/ios/Podfile.lock @@ -1149,7 +1149,7 @@ PODS: - stream-react-native-webrtc (124.0.0-rc.1): - JitsiWebRTC (~> 124.0.0) - React-Core - - stream-video-react-native (1.1.4): + - stream-video-react-native (1.2.7): - glog - RCT-Folly (= 2022.05.16.00) - React-Core @@ -1480,7 +1480,7 @@ SPEC CHECKSUMS: SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17 stream-io-video-filters-react-native: 8c345e6adf5164646696d45f9962c4199b2fe3b9 stream-react-native-webrtc: 1380525629fae21f4894535189573fb4ddb7984a - stream-video-react-native: 25880e3ff2889deca42fba87f6fa0c434fc6e5fa + stream-video-react-native: 7948f9d3bfd695f46d90f7d05b982b31b0c304a8 TOCropViewController: 80b8985ad794298fb69d3341de183f33d1853654 Yoga: 1b901a6d6eeba4e8a2e8f308f708691cdb5db312 diff --git a/yarn.lock b/yarn.lock index 2de968f2d2..0f7987c16d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8072,6 +8072,7 @@ __metadata: react-native-voip-push-notification: 3.3.1 react-test-renderer: ^18.2.0 rimraf: ^5.0.7 + rxjs: ~7.8.1 text-encoding-polyfill: 0.6.7 ts-jest: ^29.1.5 ts-node: ^10.9.2 From 68e119f5b241b912288e24ae5358c0f4b1e7423f Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot <> Date: Fri, 1 Nov 2024 11:14:48 +0000 Subject: [PATCH 06/35] chore(@stream-io/video-client): release version 1.10.2 --- packages/client/CHANGELOG.md | 7 +++++++ packages/client/package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/client/CHANGELOG.md b/packages/client/CHANGELOG.md index 51357ce4a7..c8bfcd8c55 100644 --- a/packages/client/CHANGELOG.md +++ b/packages/client/CHANGELOG.md @@ -2,6 +2,13 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +## [1.10.2](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.10.1...@stream-io/video-client-1.10.2) (2024-11-01) + + +### Bug Fixes + +* camera not enabled on foreground notifications ([#1546](https://github.com/GetStream/stream-video-js/issues/1546)) ([67c920a](https://github.com/GetStream/stream-video-js/commit/67c920ac4bca35a414b88f6c9829b08396a6260b)) + ## [1.10.1](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.10.0...@stream-io/video-client-1.10.1) (2024-10-30) diff --git a/packages/client/package.json b/packages/client/package.json index d9bab64954..21b41b8dbc 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@stream-io/video-client", - "version": "1.10.1", + "version": "1.10.2", "packageManager": "yarn@3.2.4", "main": "dist/index.cjs.js", "module": "dist/index.es.js", From 12935e68f6f01f86113cabe97d35a4daeeda4544 Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot <> Date: Fri, 1 Nov 2024 11:15:10 +0000 Subject: [PATCH 07/35] chore(@stream-io/video-react-bindings): release version 1.1.12 --- packages/react-bindings/CHANGELOG.md | 5 +++++ packages/react-bindings/package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/react-bindings/CHANGELOG.md b/packages/react-bindings/CHANGELOG.md index 23acdc0d25..a15334ac20 100644 --- a/packages/react-bindings/CHANGELOG.md +++ b/packages/react-bindings/CHANGELOG.md @@ -2,6 +2,11 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +## [1.1.12](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-bindings-1.1.11...@stream-io/video-react-bindings-1.1.12) (2024-11-01) + +### Dependency Updates + +* `@stream-io/video-client` updated to version `1.10.2` ## [1.1.11](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-bindings-1.1.10...@stream-io/video-react-bindings-1.1.11) (2024-11-01) diff --git a/packages/react-bindings/package.json b/packages/react-bindings/package.json index affe6aa24a..aa6a47dfd1 100644 --- a/packages/react-bindings/package.json +++ b/packages/react-bindings/package.json @@ -1,6 +1,6 @@ { "name": "@stream-io/video-react-bindings", - "version": "1.1.11", + "version": "1.1.12", "packageManager": "yarn@3.2.4", "main": "./dist/index.cjs.js", "module": "./dist/index.es.js", From 0ebbba8da465a6bf69ce12a3ac5e756d552317e3 Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot <> Date: Fri, 1 Nov 2024 11:15:18 +0000 Subject: [PATCH 08/35] chore(@stream-io/video-react-sdk): release version 1.7.7 --- packages/react-sdk/CHANGELOG.md | 6 ++++++ packages/react-sdk/package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/react-sdk/CHANGELOG.md b/packages/react-sdk/CHANGELOG.md index eb46808938..baf10854ee 100644 --- a/packages/react-sdk/CHANGELOG.md +++ b/packages/react-sdk/CHANGELOG.md @@ -2,6 +2,12 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +## [1.7.7](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-sdk-1.7.6...@stream-io/video-react-sdk-1.7.7) (2024-11-01) + +### Dependency Updates + +* `@stream-io/video-client` updated to version `1.10.2` +* `@stream-io/video-react-bindings` updated to version `1.1.12` ## [1.7.6](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-sdk-1.7.5...@stream-io/video-react-sdk-1.7.6) (2024-11-01) ### Dependency Updates diff --git a/packages/react-sdk/package.json b/packages/react-sdk/package.json index 8c8bc7a737..510f0ff28f 100644 --- a/packages/react-sdk/package.json +++ b/packages/react-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@stream-io/video-react-sdk", - "version": "1.7.6", + "version": "1.7.7", "packageManager": "yarn@3.2.4", "main": "./dist/index.cjs.js", "module": "./dist/index.es.js", From 5fe1b87dcfbdfad6a80252a05070faa00fcea30a Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot <> Date: Fri, 1 Nov 2024 11:15:35 +0000 Subject: [PATCH 09/35] chore(@stream-io/video-react-native-sdk): release version 1.2.9 --- packages/react-native-sdk/CHANGELOG.md | 11 +++++++++++ packages/react-native-sdk/package.json | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/react-native-sdk/CHANGELOG.md b/packages/react-native-sdk/CHANGELOG.md index e18c3dfac8..20a44ba9c4 100644 --- a/packages/react-native-sdk/CHANGELOG.md +++ b/packages/react-native-sdk/CHANGELOG.md @@ -2,6 +2,17 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +## [1.2.9](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-native-sdk-1.2.8...@stream-io/video-react-native-sdk-1.2.9) (2024-11-01) + +### Dependency Updates + +* `@stream-io/video-client` updated to version `1.10.2` +* `@stream-io/video-react-bindings` updated to version `1.1.12` + +### Bug Fixes + +* camera not enabled on foreground notifications ([#1546](https://github.com/GetStream/stream-video-js/issues/1546)) ([67c920a](https://github.com/GetStream/stream-video-js/commit/67c920ac4bca35a414b88f6c9829b08396a6260b)) + ## [1.2.8](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-native-sdk-1.2.7...@stream-io/video-react-native-sdk-1.2.8) (2024-11-01) ### Dependency Updates diff --git a/packages/react-native-sdk/package.json b/packages/react-native-sdk/package.json index c9c8bbb6e3..360bfaa849 100644 --- a/packages/react-native-sdk/package.json +++ b/packages/react-native-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@stream-io/video-react-native-sdk", - "version": "1.2.8", + "version": "1.2.9", "packageManager": "yarn@3.2.4", "main": "dist/commonjs/index.js", "module": "dist/module/index.js", From 7ed7033f2edd0f2ca61e6b1c82c550380f5b5303 Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot <> Date: Fri, 1 Nov 2024 11:15:58 +0000 Subject: [PATCH 10/35] chore(@stream-io/video-react-native-dogfood): release version 4.4.9 --- sample-apps/react-native/dogfood/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sample-apps/react-native/dogfood/package.json b/sample-apps/react-native/dogfood/package.json index 035777790e..6b9425fa83 100644 --- a/sample-apps/react-native/dogfood/package.json +++ b/sample-apps/react-native/dogfood/package.json @@ -1,6 +1,6 @@ { "name": "@stream-io/video-react-native-dogfood", - "version": "4.4.8", + "version": "4.4.9", "private": true, "scripts": { "android": "react-native run-android", From bdc4a8631a310f308a851a71b8392a2d4b7c5230 Mon Sep 17 00:00:00 2001 From: Kristian Date: Fri, 1 Nov 2024 14:23:39 +0100 Subject: [PATCH 11/35] fix: imports for useToggleCallRecording (#1548) Fix the wrong imports in the `callUtilHooks.ts` --- packages/react-bindings/src/hooks/callUtilHooks.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/react-bindings/src/hooks/callUtilHooks.ts b/packages/react-bindings/src/hooks/callUtilHooks.ts index 128b843323..e8ce9ef83f 100644 --- a/packages/react-bindings/src/hooks/callUtilHooks.ts +++ b/packages/react-bindings/src/hooks/callUtilHooks.ts @@ -1,6 +1,6 @@ import { useCallback, useEffect, useState } from 'react'; -import { useCall, useCallStateHooks } from '@stream-io/video-react-bindings'; - +import { useCall } from '../contexts'; +import { useIsCallRecordingInProgress } from './callStateHooks'; /** * Custom hook for toggling call recording in a video call. * @@ -10,7 +10,6 @@ import { useCall, useCallStateHooks } from '@stream-io/video-react-bindings'; */ export const useToggleCallRecording = () => { const call = useCall(); - const { useIsCallRecordingInProgress } = useCallStateHooks(); const isCallRecordingInProgress = useIsCallRecordingInProgress(); const [isAwaitingResponse, setIsAwaitingResponse] = useState(false); From 8ecb5b909bdf8c3612de48ba69fca6e4a3e20c40 Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot <> Date: Fri, 1 Nov 2024 13:26:26 +0000 Subject: [PATCH 12/35] chore(@stream-io/video-react-bindings): release version 1.1.13 --- packages/react-bindings/CHANGELOG.md | 7 +++++++ packages/react-bindings/package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/react-bindings/CHANGELOG.md b/packages/react-bindings/CHANGELOG.md index a15334ac20..f99983eda7 100644 --- a/packages/react-bindings/CHANGELOG.md +++ b/packages/react-bindings/CHANGELOG.md @@ -2,6 +2,13 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +## [1.1.13](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-bindings-1.1.12...@stream-io/video-react-bindings-1.1.13) (2024-11-01) + + +### Bug Fixes + +* imports for useToggleCallRecording ([#1548](https://github.com/GetStream/stream-video-js/issues/1548)) ([f6b2180](https://github.com/GetStream/stream-video-js/commit/f6b21809e95691298d5c8fec6754a886eb9a28fe)) + ## [1.1.12](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-bindings-1.1.11...@stream-io/video-react-bindings-1.1.12) (2024-11-01) ### Dependency Updates diff --git a/packages/react-bindings/package.json b/packages/react-bindings/package.json index aa6a47dfd1..bc3973f570 100644 --- a/packages/react-bindings/package.json +++ b/packages/react-bindings/package.json @@ -1,6 +1,6 @@ { "name": "@stream-io/video-react-bindings", - "version": "1.1.12", + "version": "1.1.13", "packageManager": "yarn@3.2.4", "main": "./dist/index.cjs.js", "module": "./dist/index.es.js", From 1e2d9d14280e05a5147c3d599caf4909130328df Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot <> Date: Fri, 1 Nov 2024 13:26:34 +0000 Subject: [PATCH 13/35] chore(@stream-io/video-react-sdk): release version 1.7.8 --- packages/react-sdk/CHANGELOG.md | 5 +++++ packages/react-sdk/package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/react-sdk/CHANGELOG.md b/packages/react-sdk/CHANGELOG.md index baf10854ee..21a94725fd 100644 --- a/packages/react-sdk/CHANGELOG.md +++ b/packages/react-sdk/CHANGELOG.md @@ -2,6 +2,11 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +## [1.7.8](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-sdk-1.7.7...@stream-io/video-react-sdk-1.7.8) (2024-11-01) + +### Dependency Updates + +* `@stream-io/video-react-bindings` updated to version `1.1.13` ## [1.7.7](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-sdk-1.7.6...@stream-io/video-react-sdk-1.7.7) (2024-11-01) ### Dependency Updates diff --git a/packages/react-sdk/package.json b/packages/react-sdk/package.json index 510f0ff28f..9032f6c1b6 100644 --- a/packages/react-sdk/package.json +++ b/packages/react-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@stream-io/video-react-sdk", - "version": "1.7.7", + "version": "1.7.8", "packageManager": "yarn@3.2.4", "main": "./dist/index.cjs.js", "module": "./dist/index.es.js", From b4e7153d791873c1bc0c67c7190542eb19161541 Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot <> Date: Fri, 1 Nov 2024 13:26:51 +0000 Subject: [PATCH 14/35] chore(@stream-io/video-react-native-sdk): release version 1.2.10 --- packages/react-native-sdk/CHANGELOG.md | 5 +++++ packages/react-native-sdk/package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/react-native-sdk/CHANGELOG.md b/packages/react-native-sdk/CHANGELOG.md index 20a44ba9c4..29ef58176e 100644 --- a/packages/react-native-sdk/CHANGELOG.md +++ b/packages/react-native-sdk/CHANGELOG.md @@ -2,6 +2,11 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +## [1.2.10](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-native-sdk-1.2.9...@stream-io/video-react-native-sdk-1.2.10) (2024-11-01) + +### Dependency Updates + +* `@stream-io/video-react-bindings` updated to version `1.1.13` ## [1.2.9](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-native-sdk-1.2.8...@stream-io/video-react-native-sdk-1.2.9) (2024-11-01) ### Dependency Updates diff --git a/packages/react-native-sdk/package.json b/packages/react-native-sdk/package.json index 360bfaa849..fa3526e34c 100644 --- a/packages/react-native-sdk/package.json +++ b/packages/react-native-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@stream-io/video-react-native-sdk", - "version": "1.2.9", + "version": "1.2.10", "packageManager": "yarn@3.2.4", "main": "dist/commonjs/index.js", "module": "dist/module/index.js", From f43e394123158670c2d6a0a8a466f737ffacf401 Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot <> Date: Fri, 1 Nov 2024 13:27:14 +0000 Subject: [PATCH 15/35] chore(@stream-io/video-react-native-dogfood): release version 4.4.10 --- sample-apps/react-native/dogfood/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sample-apps/react-native/dogfood/package.json b/sample-apps/react-native/dogfood/package.json index 6b9425fa83..5a03a7054e 100644 --- a/sample-apps/react-native/dogfood/package.json +++ b/sample-apps/react-native/dogfood/package.json @@ -1,6 +1,6 @@ { "name": "@stream-io/video-react-native-dogfood", - "version": "4.4.9", + "version": "4.4.10", "private": true, "scripts": { "android": "react-native run-android", From 57c88b262f754fa7158a8ab8278c1e37563802c4 Mon Sep 17 00:00:00 2001 From: Kristian Date: Fri, 1 Nov 2024 17:05:05 +0100 Subject: [PATCH 16/35] feat(design-v2): call recording flow (#1535) This PR: - completes the Call recording flow - adds the Recording modal component - moves the `useToggleCallRecording` to `useCallStateHooks` so it can be used for React Native as well ios-after ios-after ios-after --- .../react-bindings/src/hooks/callUtilHooks.ts | 1 + .../04-ui-components/call/call-top-view.mdx | 1 - packages/react-native-sdk/src/theme/colors.ts | 6 +- .../dogfood/src/components/ActiveCall.tsx | 43 +++-- .../CallControlls/BottomControls.tsx | 14 +- .../CallControlls/CallRecordingModal.tsx | 165 ++++++++++++++++++ .../CallControlls/CallStatusBadge.tsx | 90 ++++++---- .../CallControlls/RecordCallButton.tsx | 67 +++++-- .../components/CallControlls/TopControls.tsx | 22 +-- 9 files changed, 331 insertions(+), 78 deletions(-) create mode 100644 sample-apps/react-native/dogfood/src/components/CallControlls/CallRecordingModal.tsx diff --git a/packages/react-bindings/src/hooks/callUtilHooks.ts b/packages/react-bindings/src/hooks/callUtilHooks.ts index e8ce9ef83f..e4e1a74233 100644 --- a/packages/react-bindings/src/hooks/callUtilHooks.ts +++ b/packages/react-bindings/src/hooks/callUtilHooks.ts @@ -1,6 +1,7 @@ import { useCallback, useEffect, useState } from 'react'; import { useCall } from '../contexts'; import { useIsCallRecordingInProgress } from './callStateHooks'; + /** * Custom hook for toggling call recording in a video call. * diff --git a/packages/react-native-sdk/docusaurus/docs/reactnative/04-ui-components/call/call-top-view.mdx b/packages/react-native-sdk/docusaurus/docs/reactnative/04-ui-components/call/call-top-view.mdx index 27f7aad3ce..df2a24a996 100644 --- a/packages/react-native-sdk/docusaurus/docs/reactnative/04-ui-components/call/call-top-view.mdx +++ b/packages/react-native-sdk/docusaurus/docs/reactnative/04-ui-components/call/call-top-view.mdx @@ -3,7 +3,6 @@ id: call-top-view title: CallTopView --- -import ParticipantsInfoBadge from '../../common-content/ui-components/call/call-content/participants-info-badge.mdx'; import OnBackPressed from '../../common-content/ui-components/call/call-content/on-back-pressed.mdx'; import OnParticipantInfoPress from '../../common-content/ui-components/call/call-content/on-participant-info-press.mdx'; diff --git a/packages/react-native-sdk/src/theme/colors.ts b/packages/react-native-sdk/src/theme/colors.ts index 0c78ae81db..f2861e2e1b 100644 --- a/packages/react-native-sdk/src/theme/colors.ts +++ b/packages/react-native-sdk/src/theme/colors.ts @@ -36,6 +36,9 @@ const colors: ColorScheme = { iconAlertSuccess: '#00e2a1', sheetPrimary: '#000000', sheetOverlay: '#0c0d0ea6', + typePrimary: '#eff0f1', + typeSecondary: '#b0b4b7', + buttonSecondaryHover: '#323b44', buttonPrimaryDisabled: '#1b2c43', buttonPrimaryHover: '#4c8fff', @@ -46,7 +49,6 @@ const colors: ColorScheme = { buttonQuaternaryHover: '#e77b76', buttonQuaternaryPressed: '#7d3535', buttonSecondaryDisabled: '#1e262e29', - buttonSecondaryHover: '#323b44', buttonSecondaryPressed: '#101213', buttonSecondaryActiveDefault: '#005fff', buttonSecondaryActiveHover: '#4c8fff', @@ -76,9 +78,7 @@ const colors: ColorScheme = { sheetTertiary: '#19232d', typeAccent: '#00e2a1', typeOnAccent: '#eff0f1', - typePrimary: '#eff0f1', typeQuaternary: '#101213', - typeSecondary: '#b0b4b7', typeTertiary: '#656b72', }; diff --git a/sample-apps/react-native/dogfood/src/components/ActiveCall.tsx b/sample-apps/react-native/dogfood/src/components/ActiveCall.tsx index b5a17452d7..fcf638d280 100644 --- a/sample-apps/react-native/dogfood/src/components/ActiveCall.tsx +++ b/sample-apps/react-native/dogfood/src/components/ActiveCall.tsx @@ -7,18 +7,18 @@ import { import { ActivityIndicator, StatusBar, StyleSheet, View } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { ParticipantsInfoList } from './ParticipantsInfoList'; -import { - CallControlsComponent, - BottomControlsProps, -} from './CallControlls/BottomControls'; +import { BottomControls } from './CallControlls/BottomControls'; import { useOrientation } from '../hooks/useOrientation'; import { Z_INDEX } from '../constants'; import { TopControls } from './CallControlls/TopControls'; import { useLayout } from '../contexts/LayoutContext'; +import { useToggleCallRecording } from '@stream-io/video-react-bindings'; -type ActiveCallProps = BottomControlsProps & { +type ActiveCallProps = { onHangupCallHandler?: () => void; onCallEnded: () => void; + onChatOpenHandler: () => void; + unreadCountIndicator: number; }; export const ActiveCall = ({ @@ -45,15 +45,38 @@ export const ActiveCall = ({ }); }, [call, onCallEnded]); - const CustomControlsComponent = useCallback(() => { + const { toggleCallRecording, isAwaitingResponse, isCallRecordingInProgress } = + useToggleCallRecording(); + + const CustomBottomControls = useCallback(() => { return ( - + ); + }, [ + onChatOpenHandler, + onOpenCallParticipantsInfo, + unreadCountIndicator, + toggleCallRecording, + isAwaitingResponse, + isCallRecordingInProgress, + ]); + + const CustomTopControls = useCallback(() => { + return ( + ); - }, [onChatOpenHandler, onOpenCallParticipantsInfo, unreadCountIndicator]); + }, [isAwaitingResponse, isCallRecordingInProgress, onHangupCallHandler]); if (!call) { return ; @@ -71,8 +94,8 @@ export const ActiveCall = ({ diff --git a/sample-apps/react-native/dogfood/src/components/CallControlls/BottomControls.tsx b/sample-apps/react-native/dogfood/src/components/CallControlls/BottomControls.tsx index 8079d2c233..a4f95cd2fb 100644 --- a/sample-apps/react-native/dogfood/src/components/CallControlls/BottomControls.tsx +++ b/sample-apps/react-native/dogfood/src/components/CallControlls/BottomControls.tsx @@ -22,12 +22,18 @@ export type BottomControlsProps = Pick< onChatOpenHandler?: () => void; onParticipantInfoPress?: () => void; unreadCountIndicator?: number; + toggleCallRecording: () => Promise; + isAwaitingResponse: boolean; + isCallRecordingInProgress: boolean; }; -export const CallControlsComponent = ({ +export const BottomControls = ({ onChatOpenHandler, unreadCountIndicator, onParticipantInfoPress, + toggleCallRecording, + isAwaitingResponse, + isCallRecordingInProgress, }: BottomControlsProps) => { const { useMicrophoneState } = useCallStateHooks(); const { isSpeakingWhileMuted } = useMicrophoneState(); @@ -46,7 +52,11 @@ export const CallControlsComponent = ({ - + diff --git a/sample-apps/react-native/dogfood/src/components/CallControlls/CallRecordingModal.tsx b/sample-apps/react-native/dogfood/src/components/CallControlls/CallRecordingModal.tsx new file mode 100644 index 0000000000..97ec6896fd --- /dev/null +++ b/sample-apps/react-native/dogfood/src/components/CallControlls/CallRecordingModal.tsx @@ -0,0 +1,165 @@ +import { useTheme } from '@stream-io/video-react-native-sdk'; +import { IconWrapper } from '@stream-io/video-react-native-sdk/src/icons'; +import { RecordCall } from '@stream-io/video-react-native-sdk/src/icons/RecordCall'; +import React, { useMemo } from 'react'; +import { + Modal, + View, + Text, + TouchableOpacity, + TouchableWithoutFeedback, + StyleSheet, +} from 'react-native'; + +interface CallRecordingModalProps { + visible: boolean; + isLoading: boolean; + onCancel: () => void; + onConfirm: () => void; + message: string; + title: string; + confirmButton: string; + cancelButton: string; + isEndRecordingModal: boolean; +} + +export const CallRecordingModal: React.FC = ({ + visible, + isLoading, + onCancel, + onConfirm, + message, + title, + confirmButton, + cancelButton, + isEndRecordingModal, +}) => { + const styles = useStyles(isEndRecordingModal); + const { + theme: { colors, variants }, + } = useTheme(); + + return ( + + + + + + + + + + + + {title} + + {message} + + + + {cancelButton} + + + {isLoading ? ( + + Loading... + + ) : ( + {confirmButton} + )} + + + + + + + ); +}; + +const useStyles = (isEndRecordingModal: boolean) => { + const { theme } = useTheme(); + return useMemo( + () => + StyleSheet.create({ + overlay: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + }, + modalView: { + backgroundColor: theme.colors.sheetSecondary, + borderRadius: theme.variants.borderRadiusSizes.lg, + padding: theme.variants.spacingSizes.xl, + width: '80%', + maxWidth: 380, + }, + content: { + marginBottom: theme.variants.spacingSizes.xl, + }, + headerContainer: { + flexDirection: 'row', + alignItems: 'center', + marginBottom: theme.variants.spacingSizes.sm, + }, + iconContainer: { + display: 'flex', + marginRight: theme.variants.spacingSizes.sm, + }, + title: { + color: theme.colors.typePrimary, + fontSize: theme.variants.fontSizes.lg, + fontWeight: '600', + textAlign: 'center', + }, + message: { + color: theme.colors.typeSecondary, + fontSize: theme.variants.fontSizes.md, + fontWeight: '400', + textAlign: 'left', + }, + buttonContainer: { + flexDirection: 'row', + justifyContent: 'space-between', + gap: theme.variants.spacingSizes.md, + }, + button: { + flex: 1, + borderRadius: theme.variants.roundButtonSizes.md, + justifyContent: 'center', + alignItems: 'center', + }, + cancelButton: { + backgroundColor: theme.colors.sheetSecondary, + height: 32, + borderWidth: 1, + borderColor: theme.colors.buttonSecondaryHover, + }, + confirmButton: { + height: 32, + backgroundColor: isEndRecordingModal + ? theme.colors.iconAlertWarning + : theme.colors.buttonPrimaryDefault, + }, + buttonText: { + color: 'white', + fontSize: 13, + fontWeight: '600', + }, + }), + [theme, isEndRecordingModal], + ); +}; diff --git a/sample-apps/react-native/dogfood/src/components/CallControlls/CallStatusBadge.tsx b/sample-apps/react-native/dogfood/src/components/CallControlls/CallStatusBadge.tsx index 7698b8f397..ffb189ef3f 100644 --- a/sample-apps/react-native/dogfood/src/components/CallControlls/CallStatusBadge.tsx +++ b/sample-apps/react-native/dogfood/src/components/CallControlls/CallStatusBadge.tsx @@ -4,27 +4,26 @@ import { CallDuration } from '../../assets/CallDuration'; import { RecordCall } from '@stream-io/video-react-native-sdk/src/icons/RecordCall'; import { IconWrapper } from '@stream-io/video-react-native-sdk/src/icons'; import { useTheme } from '@stream-io/video-react-native-sdk'; +import { useCallStateHooks } from '@stream-io/video-react-bindings'; -/** - * Props for the CallStatusBadge component. - */ -interface CallStatusBadgeProps { - /** - * Indicates if the call is currently being recorded. - * When true, it shows "Recording in progress..." and a specific icon. - * When false, it shows the elapsed time. - */ - isCallRecorded: boolean; -} +const formatTime = (seconds: number) => { + const date = new Date(0); + date.setSeconds(seconds); + const format = date.toISOString(); + const hours = format.substring(11, 13); + const minutes = format.substring(14, 16); + const seconds_str = format.substring(17, 19); + return `${hours !== '00' ? hours + ':' : ''}${minutes}:${seconds_str}`; +}; + +export type CallStatusBadgeProps = { + isCallRecordingInProgress: boolean; + isAwaitingResponse: boolean; +}; -/** - * CallStatusBadge component to display the current status of a call. - * It shows either a recording message or the elapsed time, with an accompanying icon. - * - * @param {CallStatusBadgeProps} props - The props for the component. - */ export const CallStatusBadge: React.FC = ({ - isCallRecorded, + isCallRecordingInProgress, + isAwaitingResponse, }) => { const { theme: { @@ -34,27 +33,43 @@ export const CallStatusBadge: React.FC = ({ } = useTheme(); // TODO: replace this with useDuration when that https://github.com/GetStream/stream-video-js/pull/1528 is merged - const [elapsedSeconds, setElapsedSeconds] = useState(0); + const [elapsed, setElapsed] = useState('00:00'); + const { useCallSession } = useCallStateHooks(); + const session = useCallSession(); + const startedAt = session?.started_at; + const startedAtDate = useMemo(() => { + if (!startedAt) { + return Date.now(); + } + const date = new Date(startedAt).getTime(); + return isNaN(date) ? Date.now() : date; + }, [startedAt]); + useEffect(() => { - const startedAt = new Date().getTime(); - setElapsedSeconds(Math.floor((Date.now() - startedAt) / 1000)); - const intervalId = setInterval(() => { - setElapsedSeconds((prevSeconds) => prevSeconds + 1); + const initialElapsedSeconds = Math.max( + 0, + (Date.now() - startedAtDate) / 1000, + ); + + setElapsed(formatTime(initialElapsedSeconds)); + + const interval = setInterval(() => { + const elapsedSeconds = (Date.now() - startedAtDate) / 1000; + setElapsed(formatTime(elapsedSeconds)); }, 1000); - return () => clearInterval(intervalId); - }, []); - const styles = useStyles(isCallRecorded); + return () => clearInterval(interval); + }, [startedAtDate]); - // Format duration to MM:SS - const minutes = Math.floor(elapsedSeconds / 60) - .toString() - .padStart(2, '0'); - const seconds = (elapsedSeconds % 60).toString().padStart(2, '0'); - const timestamp = `${minutes}:${seconds}`; - const text = isCallRecorded ? 'Recording in progress...' : timestamp; + const styles = useStyles(isAwaitingResponse); + const recordingMessage = isCallRecordingInProgress + ? 'Stopping recording...' + : 'Recording in progress...'; - const icon = isCallRecorded ? ( + let text = isAwaitingResponse ? recordingMessage : elapsed; + const showRecordingIcon = isCallRecordingInProgress || isAwaitingResponse; + + const icon = showRecordingIcon ? ( ) : ( @@ -70,9 +85,8 @@ export const CallStatusBadge: React.FC = ({ ); }; -const useStyles = (isCallRecorded: boolean) => { +const useStyles = (isLoading: boolean) => { const { theme } = useTheme(); - return useMemo( () => StyleSheet.create({ @@ -85,7 +99,7 @@ const useStyles = (isCallRecorded: boolean) => { paddingRight: 5, justifyContent: 'center', alignItems: 'center', - width: isCallRecorded ? 200 : 80, + width: isLoading ? 200 : 80, }, text: { color: theme.colors.typePrimary, @@ -100,6 +114,6 @@ const useStyles = (isCallRecorded: boolean) => { marginRight: 5, }, }), - [theme, isCallRecorded], + [theme, isLoading], ); }; diff --git a/sample-apps/react-native/dogfood/src/components/CallControlls/RecordCallButton.tsx b/sample-apps/react-native/dogfood/src/components/CallControlls/RecordCallButton.tsx index a3484758a2..b41b4490e3 100644 --- a/sample-apps/react-native/dogfood/src/components/CallControlls/RecordCallButton.tsx +++ b/sample-apps/react-native/dogfood/src/components/CallControlls/RecordCallButton.tsx @@ -5,44 +5,83 @@ import { } from '@stream-io/video-react-native-sdk'; import { RecordCall } from '@stream-io/video-react-native-sdk/src/icons/RecordCall'; import { IconWrapper } from '@stream-io/video-react-native-sdk/src/icons'; +import { CallRecordingModal } from './CallRecordingModal'; /** * The props for the Record Call Button in the Call Controls. */ export type RecordCallButtonProps = { - /** - * Handler to be called when the record call button is pressed. - * @returns void - */ onPressHandler?: () => void; + toggleCallRecording: () => Promise; + isAwaitingResponse: boolean; + isCallRecordingInProgress: boolean; }; /** * The Record Call Button is used in the Call Controls component * and allows the user to toggle call recording. */ -export const RecordCallButton = ({ onPressHandler }: RecordCallButtonProps) => { +export const RecordCallButton = ({ + onPressHandler, + toggleCallRecording, + isAwaitingResponse, + isCallRecordingInProgress, +}: RecordCallButtonProps) => { const { theme: { colors, recordCallButton, variants }, } = useTheme(); - const [isRecording, setIsRecording] = useState(false); - const buttonColor = isRecording + + const [isStopRecordingModalOpen, setIsStopRecordingModalOpen] = + useState(false); + + const buttonColor = isCallRecordingInProgress ? colors.buttonSecondaryWarningDefault : colors.buttonSecondaryDefault; - // TODO: implement PBE-5871 [Demo App] Call Recording flow + const onPress = async () => { + if (onPressHandler) { + onPressHandler(); + } + if (isCallRecordingInProgress) { + setIsStopRecordingModalOpen(true); + } else { + await toggleCallRecording(); + } + }; + + const endRecording = ( + { + if (!isAwaitingResponse) { + setIsStopRecordingModalOpen(false); + } + }} + onConfirm={async () => { + if (!isAwaitingResponse) { + await toggleCallRecording(); + setIsStopRecordingModalOpen(false); + } + }} + /> + ); + return ( { - if (onPressHandler) { - onPressHandler(); - } - setIsRecording(!isRecording); - }} + onPress={onPress} color={buttonColor} style={recordCallButton} + disabled={isAwaitingResponse} + disabledColor={colors.buttonPrimaryDisabled} > + {endRecording} void; + isCallRecordingInProgress: boolean; + isAwaitingResponse: boolean; }; -export const TopControls = ({ onHangupCallHandler }: TopControlsProps) => { +export const TopControls = ({ + onHangupCallHandler, + isCallRecordingInProgress, + isAwaitingResponse, +}: TopControlsProps) => { const [topControlsHeight, setTopControlsHeight] = useState(0); const [topControlsWidth, setTopControlsWidth] = useState(0); const styles = useStyles(); - // TODO: replace this with real data implement PBE-5871 [Demo App] Call Recording flow - const [isCallRecorded] = useState(false); - const onLayout: React.ComponentProps['onLayout'] = (event) => { const { height, width } = event.nativeEvent.layout; if (setTopControlsHeight) { @@ -43,11 +42,14 @@ export const TopControls = ({ onHangupCallHandler }: TopControlsProps) => { - {!isCallRecorded && } + {!isAwaitingResponse && } - + From f29756d2d13e4a9b81b7efb5b43dee2f7202b5e3 Mon Sep 17 00:00:00 2001 From: Kristian Date: Fri, 1 Nov 2024 17:05:25 +0100 Subject: [PATCH 17/35] feat(design-v2): bottom controls drawer component with reactions flow (#1539) This PR: - adds the More action buttons drawer component - the emoji reactions are implemented and that completes the reactions flow - the other buttons are not functional and their actions/flows will be implemented in other PRs Screenshot at Oct 29 14-24-22 --- .../FloatingView/AnimatedFloatingView.tsx | 5 +- .../FloatingView/ReanimatedFloatingView.tsx | 6 +- .../FloatingView/common.ts | 6 +- .../ParticipantView/ParticipantReaction.tsx | 57 ++-- .../react-native-sdk/src/constants/index.ts | 30 +- .../src/icons/CameraSwitch.tsx | 2 +- .../react-native-sdk/src/icons/Effects.tsx | 2 +- packages/react-native-sdk/src/theme/theme.ts | 2 + .../dogfood/src/assets/ClosedCaptions.tsx | 19 ++ .../dogfood/src/assets/Feedback.tsx | 19 ++ .../dogfood/src/assets/NoiseCancelation.tsx | 19 ++ .../dogfood/src/assets/RaiseHand.tsx | 19 ++ .../react-native/dogfood/src/assets/Stats.tsx | 19 ++ .../src/components/BottomControlsDrawer.tsx | 312 ++++++++++++++++++ .../CallControlls/BottomControls.tsx | 4 +- .../CallControlls/MoreActionsButton.tsx | 73 +++- .../dogfood/src/constants/index.ts | 1 + sample-apps/react-native/dogfood/src/theme.ts | 3 + 18 files changed, 555 insertions(+), 43 deletions(-) create mode 100644 sample-apps/react-native/dogfood/src/assets/ClosedCaptions.tsx create mode 100644 sample-apps/react-native/dogfood/src/assets/Feedback.tsx create mode 100644 sample-apps/react-native/dogfood/src/assets/NoiseCancelation.tsx create mode 100644 sample-apps/react-native/dogfood/src/assets/RaiseHand.tsx create mode 100644 sample-apps/react-native/dogfood/src/assets/Stats.tsx create mode 100644 sample-apps/react-native/dogfood/src/components/BottomControlsDrawer.tsx diff --git a/packages/react-native-sdk/src/components/Participant/FloatingParticipantView/FloatingView/AnimatedFloatingView.tsx b/packages/react-native-sdk/src/components/Participant/FloatingParticipantView/FloatingView/AnimatedFloatingView.tsx index 1f46fe288d..99088df5a5 100644 --- a/packages/react-native-sdk/src/components/Participant/FloatingParticipantView/FloatingView/AnimatedFloatingView.tsx +++ b/packages/react-native-sdk/src/components/Participant/FloatingParticipantView/FloatingView/AnimatedFloatingView.tsx @@ -15,6 +15,7 @@ import { floatingChildViewContainerStyle, } from './common'; import { getLogger } from '@stream-io/video-client'; +import { useTheme } from '../../../..'; const AnimatedFloatingView = ({ initialAlignment, @@ -29,6 +30,7 @@ const AnimatedFloatingView = ({ const translateRef = useRef(new Animated.ValueXY()); const opacity = useRef(new Animated.Value(0)); + const { theme } = useTheme(); const [rectangle, setRectangle] = React.useState(); // we need to force update the component when the rectangle is available @@ -58,6 +60,7 @@ const AnimatedFloatingView = ({ width: rectangle.width, height: rectangle.height, }, + topOffset: theme.floatingParticipantsView.topPosition, }); const { x, y } = snapAlignments[initialAlignment]; snapAlignmentsRef.current = snapAlignments; @@ -66,7 +69,7 @@ const AnimatedFloatingView = ({ opacity.current.setValue(1); forceUpdate(); // any time the dependency changes, we need to snap to the new alignment - }, [initialAlignment, rectangle, containerWidth, containerHeight]); + }, [initialAlignment, rectangle, containerWidth, containerHeight, theme]); const panResponder = useRef( PanResponder.create({ diff --git a/packages/react-native-sdk/src/components/Participant/FloatingParticipantView/FloatingView/ReanimatedFloatingView.tsx b/packages/react-native-sdk/src/components/Participant/FloatingParticipantView/FloatingView/ReanimatedFloatingView.tsx index f0111d9f0a..432366165c 100644 --- a/packages/react-native-sdk/src/components/Participant/FloatingParticipantView/FloatingView/ReanimatedFloatingView.tsx +++ b/packages/react-native-sdk/src/components/Participant/FloatingParticipantView/FloatingView/ReanimatedFloatingView.tsx @@ -7,6 +7,7 @@ import { floatingChildViewContainerStyle, FloatingViewProps, } from './common'; +import { useTheme } from '../../../..'; type GestureHandlerExportsType = typeof import('react-native-gesture-handler'); type ReanimatedNamespaceType = typeof import('react-native-reanimated').default; type ReanimatedExportsType = typeof import('react-native-reanimated'); @@ -54,6 +55,7 @@ try { // we don't want to show the floating view until we have the layout rectangle const opacity = useSharedValue(0); const [rectangle, setRectangle] = React.useState(); + const { theme } = useTheme(); const snapAlignments = useMemo(() => { if (!rectangle) { @@ -64,7 +66,6 @@ try { [FloatingViewAlignment.bottomRight]: { x: 0, y: 0 }, }; } - return getSnapAlignments({ rootContainerDimensions: { width: containerWidth, @@ -74,8 +75,9 @@ try { width: rectangle.width, height: rectangle.height, }, + topOffset: theme.floatingParticipantsView.topPosition, }); - }, [rectangle, containerWidth, containerHeight]); + }, [rectangle, containerWidth, containerHeight, theme]); const dragGesture = Gesture.Pan() .onStart((_e) => { diff --git a/packages/react-native-sdk/src/components/Participant/FloatingParticipantView/FloatingView/common.ts b/packages/react-native-sdk/src/components/Participant/FloatingParticipantView/FloatingView/common.ts index 0a5f8a4b4e..769f2cbada 100644 --- a/packages/react-native-sdk/src/components/Participant/FloatingParticipantView/FloatingView/common.ts +++ b/packages/react-native-sdk/src/components/Participant/FloatingParticipantView/FloatingView/common.ts @@ -23,20 +23,22 @@ export type SnapAlignments = Record< export function getSnapAlignments({ rootContainerDimensions, floatingViewDimensions, + topOffset, }: { rootContainerDimensions: { width: number; height: number }; floatingViewDimensions: { width: number; height: number }; + topOffset: number; }): SnapAlignments { const right = rootContainerDimensions.width - floatingViewDimensions.width; const bottom = rootContainerDimensions.height - floatingViewDimensions.height; const snapOffsets = { [FloatingViewAlignment.topLeft]: { x: 0, - y: 0, + y: topOffset, }, [FloatingViewAlignment.topRight]: { x: right, - y: 0, + y: topOffset, }, [FloatingViewAlignment.bottomLeft]: { x: 0, diff --git a/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantReaction.tsx b/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantReaction.tsx index 1d8e7c52d4..cac5d2af64 100644 --- a/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantReaction.tsx +++ b/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantReaction.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from 'react'; +import React, { useEffect, useMemo } from 'react'; import { StyleSheet, Text, View } from 'react-native'; import { useCall } from '@stream-io/video-react-bindings'; import { Z_INDEX, defaultEmojiReactions } from '../../../constants'; @@ -32,12 +32,9 @@ export const ParticipantReaction = ({ }: ParticipantReactionProps) => { const { reaction, sessionId } = participant; const call = useCall(); + const styles = useStyles(); const { - theme: { - typefaces, - variants: { iconSizes }, - participantReaction, - }, + theme: { typefaces, participantReaction }, } = useTheme(); useEffect(() => { @@ -60,26 +57,34 @@ export const ParticipantReaction = ({ ); return ( - - - {currentReaction?.icon} - - + currentReaction?.icon != null && ( + + + {currentReaction?.icon} + + + ) ); }; -const styles = StyleSheet.create({ - container: { - alignSelf: 'flex-start', - zIndex: Z_INDEX.IN_FRONT, - }, -}); +const useStyles = () => { + const { theme } = useTheme(); + return useMemo( + () => + StyleSheet.create({ + container: { + alignSelf: 'flex-end', + marginRight: theme.variants.spacingSizes.md, + marginTop: theme.variants.spacingSizes.md, + height: theme.variants.roundButtonSizes.md, + width: theme.variants.roundButtonSizes.md, + borderRadius: theme.variants.borderRadiusSizes.sm, + backgroundColor: theme.colors.sheetOverlay, + alignItems: 'center', + justifyContent: 'center', + zIndex: Z_INDEX.IN_FRONT, + }, + }), + [theme] + ); +}; diff --git a/packages/react-native-sdk/src/constants/index.ts b/packages/react-native-sdk/src/constants/index.ts index 42241a3ef0..67774527bb 100644 --- a/packages/react-native-sdk/src/constants/index.ts +++ b/packages/react-native-sdk/src/constants/index.ts @@ -9,6 +9,12 @@ export const FLOATING_VIDEO_VIEW_STYLE = { export const LOBBY_VIDEO_VIEW_HEIGHT = 240; export const defaultEmojiReactions: StreamReactionType[] = [ + { + type: 'reaction', + emoji_code: ':rolling_on_the_floor_laughing:', + custom: {}, + icon: '๐Ÿคฃ', + }, { type: 'reaction', emoji_code: ':like:', @@ -16,10 +22,16 @@ export const defaultEmojiReactions: StreamReactionType[] = [ icon: '๐Ÿ‘', }, { - type: 'raised-hand', - emoji_code: ':raise-hand:', + type: 'reaction', + emoji_code: ':rocket:', custom: {}, - icon: 'โœ‹', + icon: '๐Ÿš€', + }, + { + type: 'reaction', + emoji_code: ':dislike:', + custom: {}, + icon: '๐Ÿ‘Ž', }, { type: 'reaction', @@ -27,6 +39,18 @@ export const defaultEmojiReactions: StreamReactionType[] = [ custom: {}, icon: '๐ŸŽ‰', }, + { + type: 'reaction', + emoji_code: ':raised-hands:', + custom: {}, + icon: '๐Ÿ™Œ', + }, + { + type: 'raised-hand', + emoji_code: ':raised-hand:', + custom: {}, + icon: 'โœ‹', + }, ]; export const Z_INDEX = { diff --git a/packages/react-native-sdk/src/icons/CameraSwitch.tsx b/packages/react-native-sdk/src/icons/CameraSwitch.tsx index 62bb662cd2..b99fc61b8e 100644 --- a/packages/react-native-sdk/src/icons/CameraSwitch.tsx +++ b/packages/react-native-sdk/src/icons/CameraSwitch.tsx @@ -8,7 +8,7 @@ type Props = { }; export const CameraSwitch = ({ color, size }: Props) => ( - + ( - + ( + + + +); + +export default ClosedCaptions; diff --git a/sample-apps/react-native/dogfood/src/assets/Feedback.tsx b/sample-apps/react-native/dogfood/src/assets/Feedback.tsx new file mode 100644 index 0000000000..23a661ea0b --- /dev/null +++ b/sample-apps/react-native/dogfood/src/assets/Feedback.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { Svg, Path } from 'react-native-svg'; +import { ColorValue } from 'react-native/types'; + +type Props = { + color: ColorValue; + size: number; +}; + +const Feedback = ({ color, size }: Props) => ( + + + +); + +export default Feedback; diff --git a/sample-apps/react-native/dogfood/src/assets/NoiseCancelation.tsx b/sample-apps/react-native/dogfood/src/assets/NoiseCancelation.tsx new file mode 100644 index 0000000000..7263a99be4 --- /dev/null +++ b/sample-apps/react-native/dogfood/src/assets/NoiseCancelation.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { Svg, Path } from 'react-native-svg'; +import { ColorValue } from 'react-native/types'; + +type Props = { + color: ColorValue; + size: number; +}; + +const NoiseCancelation = ({ color, size }: Props) => ( + + + +); + +export default NoiseCancelation; diff --git a/sample-apps/react-native/dogfood/src/assets/RaiseHand.tsx b/sample-apps/react-native/dogfood/src/assets/RaiseHand.tsx new file mode 100644 index 0000000000..1cc6b52cde --- /dev/null +++ b/sample-apps/react-native/dogfood/src/assets/RaiseHand.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { Svg, Path } from 'react-native-svg'; +import { ColorValue } from 'react-native/types'; + +type Props = { + color: ColorValue; + size: number; +}; + +const RaiseHand = ({ color, size }: Props) => ( + + + +); + +export default RaiseHand; diff --git a/sample-apps/react-native/dogfood/src/assets/Stats.tsx b/sample-apps/react-native/dogfood/src/assets/Stats.tsx new file mode 100644 index 0000000000..213762aa42 --- /dev/null +++ b/sample-apps/react-native/dogfood/src/assets/Stats.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { Svg, Path } from 'react-native-svg'; +import { ColorValue } from 'react-native/types'; + +type Props = { + color: ColorValue; + size: number; +}; + +const Stats = ({ color, size }: Props) => ( + + + +); + +export default Stats; diff --git a/sample-apps/react-native/dogfood/src/components/BottomControlsDrawer.tsx b/sample-apps/react-native/dogfood/src/components/BottomControlsDrawer.tsx new file mode 100644 index 0000000000..07f4e5dd18 --- /dev/null +++ b/sample-apps/react-native/dogfood/src/components/BottomControlsDrawer.tsx @@ -0,0 +1,312 @@ +import { + SendReactionRequest, + useCall, + useTheme, + getLogger, +} from '@stream-io/video-react-native-sdk'; +import { defaultEmojiReactions } from '@stream-io/video-react-native-sdk/src/constants'; + +import React, { useEffect, useMemo, useRef } from 'react'; +import { + Modal, + View, + Text, + TouchableOpacity, + FlatList, + StyleSheet, + SafeAreaView, + Animated, + TouchableWithoutFeedback, + Dimensions, + PanResponder, + Easing, +} from 'react-native'; +import { BOTTOM_CONTROLS_HEIGHT } from '../constants'; +import RaiseHand from '../assets/RaiseHand'; + +export type DrawerOption = { + id: string; + label: string; + icon?: JSX.Element; + onPress: () => void; +}; + +type DrawerProps = { + isVisible: boolean; + onClose: () => void; + options: DrawerOption[]; +}; + +export const BottomControlsDrawer: React.FC = ({ + isVisible, + onClose, + options, +}) => { + const { theme } = useTheme(); + const screenHeight = Dimensions.get('window').height; + const drawerHeight = screenHeight * 0.8; + const styles = useStyles(); + const call = useCall(); + + // negative offset is needed so the drawer component start above the bottom controls + const offset = -BOTTOM_CONTROLS_HEIGHT; + + const translateY = useRef( + new Animated.Value(drawerHeight + offset), + ).current; + + const SNAP_TOP = offset; + const SNAP_BOTTOM = drawerHeight + offset; + const SNAP_MIDDLE = drawerHeight * 0.5; + + const getClosestSnapPoint = (y: number) => { + const points = [SNAP_TOP, SNAP_MIDDLE, SNAP_BOTTOM]; + return points.reduce((prev, curr) => + Math.abs(curr - y) < Math.abs(prev - y) ? curr : prev, + ); + }; + + const panResponder = useRef( + PanResponder.create({ + onStartShouldSetPanResponder: () => true, + onMoveShouldSetPanResponder: () => true, + onPanResponderGrant: () => { + translateY.setOffset(translateY._value); + translateY.setValue(0); + }, + onPanResponderMove: (_, gestureState) => { + translateY.setValue(gestureState.dy); + }, + onPanResponderRelease: () => { + translateY.flattenOffset(); + const currentPosition = translateY._value; + const snapPoint = getClosestSnapPoint(currentPosition); + + if (snapPoint === SNAP_BOTTOM) { + onClose(); + } else { + Animated.spring(translateY, { + toValue: snapPoint, + useNativeDriver: true, + bounciness: 4, + }).start(); + } + }, + }), + ).current; + + useEffect(() => { + if (isVisible) { + Animated.spring(translateY, { + toValue: SNAP_TOP, + useNativeDriver: true, + bounciness: 4, + }).start(); + } else { + Animated.timing(translateY, { + toValue: SNAP_BOTTOM, + duration: 300, + useNativeDriver: true, + }).start(); + } + }, [isVisible, SNAP_BOTTOM, SNAP_TOP, translateY]); + + const elasticAnimRef = useRef(new Animated.Value(0.5)); + + const onCloseReaction = (reaction?: SendReactionRequest) => { + if (reaction) { + call?.sendReaction(reaction).catch((e) => { + const logger = getLogger(['ReactionsPicker']); + logger('error', 'Error on onClose-sendReaction', e, reaction); + }); + } + Animated.timing(elasticAnimRef.current, { + toValue: 0.2, + duration: 150, + useNativeDriver: true, + easing: Easing.linear, + }).start(onClose); + }; + + const dragIndicator = ( + + + + ); + + const emojiReactions = ( + + {defaultEmojiReactions.map((item) => ( + + { + onCloseReaction({ + type: item.type, + custom: item.custom, + emoji_code: item.emoji_code, + }); + }} + > + {item.icon} + + + ))} + + ); + + const raiseHand = ( + { + onCloseReaction({ + type: 'raised-hand', + emoji_code: ':raised-hand:', + custom: {}, + }); + }} + > + + + + {'Raise hand'} + + ); + + const otherButtons = ( + item.id} + renderItem={({ item }) => ( + + {item.icon && {item.icon}} + {item.label} + + )} + /> + ); + + return ( + + + + + + {dragIndicator} + {emojiReactions} + {raiseHand} + {otherButtons} + + + + + + ); +}; + +const useStyles = () => { + const { + theme: { colors, variants }, + } = useTheme(); + return useMemo( + () => + StyleSheet.create({ + overlay: { + flex: 1, + justifyContent: 'flex-end', + }, + safeArea: { + flex: 1, + justifyContent: 'flex-end', + }, + container: { + backgroundColor: colors.sheetPrimary, + borderTopLeftRadius: variants.borderRadiusSizes.lg, + borderTopRightRadius: variants.borderRadiusSizes.lg, + padding: variants.spacingSizes.md, + maxHeight: '80%', + }, + dragIndicator: { + width: '100%', + height: variants.spacingSizes.xs, + alignItems: 'center', + justifyContent: 'center', + marginBottom: variants.spacingSizes.md, + }, + dragIndicatorBar: { + width: 36, + height: 5, + backgroundColor: colors.buttonSecondaryDefault, + borderRadius: 2, + }, + emojiContainer: { + width: variants.roundButtonSizes.lg, + height: variants.roundButtonSizes.lg, + padding: variants.spacingSizes.xs, + borderRadius: variants.borderRadiusSizes.lg, + backgroundColor: colors.buttonSecondaryDefault, + marginBottom: variants.spacingSizes.sm, + alignItems: 'center', + justifyContent: 'center', + }, + emojiRow: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + flexWrap: 'wrap', + }, + emojiText: { + fontSize: 25, + }, + option: { + flexDirection: 'row', + alignItems: 'center', + borderWidth: 2, + borderRadius: variants.borderRadiusSizes.lg, + paddingHorizontal: variants.spacingSizes.md, + height: variants.roundButtonSizes.lg, + backgroundColor: colors.buttonSecondaryDefault, + marginBottom: variants.spacingSizes.xs, + }, + raiseHand: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + borderWidth: 2, + borderRadius: variants.borderRadiusSizes.lg, + paddingHorizontal: variants.spacingSizes.md, + height: variants.roundButtonSizes.lg, + backgroundColor: colors.buttonSecondaryDefault, + marginBottom: variants.spacingSizes.sm, + }, + iconContainer: { + marginRight: variants.spacingSizes.sm, + }, + handIconContainer: { + marginRight: variants.spacingSizes.sm, + marginTop: variants.spacingSizes.xs, + }, + label: { + fontSize: variants.fontSizes.md, + color: colors.iconPrimaryDefault, + fontWeight: '600', + }, + screen: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + }, + }), + [variants, colors], + ); +}; diff --git a/sample-apps/react-native/dogfood/src/components/CallControlls/BottomControls.tsx b/sample-apps/react-native/dogfood/src/components/CallControlls/BottomControls.tsx index a4f95cd2fb..eb7b4b7127 100644 --- a/sample-apps/react-native/dogfood/src/components/CallControlls/BottomControls.tsx +++ b/sample-apps/react-native/dogfood/src/components/CallControlls/BottomControls.tsx @@ -8,7 +8,7 @@ import { import React, { useMemo } from 'react'; import { StyleSheet, Text, View } from 'react-native'; import { appTheme } from '../../theme'; -import { Z_INDEX } from '../../constants'; +import { BOTTOM_CONTROLS_HEIGHT, Z_INDEX } from '../../constants'; import { MoreActionsButton } from './MoreActionsButton'; import { ParticipantsButton } from './ParticipantsButton'; import { ChatButton } from './ChatButton'; @@ -80,7 +80,7 @@ const useStyles = (showMicLabel: boolean) => { paddingVertical: !showMicLabel ? theme.variants.spacingSizes.md : 0, paddingHorizontal: theme.variants.spacingSizes.md, backgroundColor: theme.colors.sheetPrimary, - height: 76, + height: BOTTOM_CONTROLS_HEIGHT, }, speakingLabelContainer: { backgroundColor: appTheme.colors.static_overlay, diff --git a/sample-apps/react-native/dogfood/src/components/CallControlls/MoreActionsButton.tsx b/sample-apps/react-native/dogfood/src/components/CallControlls/MoreActionsButton.tsx index a884cadd37..113e9b31a4 100644 --- a/sample-apps/react-native/dogfood/src/components/CallControlls/MoreActionsButton.tsx +++ b/sample-apps/react-native/dogfood/src/components/CallControlls/MoreActionsButton.tsx @@ -5,6 +5,11 @@ import { } from '@stream-io/video-react-native-sdk'; import { IconWrapper } from '@stream-io/video-react-native-sdk/src/icons'; import MoreActions from '../../assets/MoreActions'; +import { BottomControlsDrawer, DrawerOption } from '../BottomControlsDrawer'; +import NoiseCancelation from '../../assets/NoiseCancelation'; +import ClosedCaptions from '../../assets/ClosedCaptions'; +import Stats from '../../assets/Stats'; +import Feedback from '../../assets/Feedback'; /** * The props for the More Actions Button in the Call Controls. @@ -25,26 +30,84 @@ export const MoreActionsButton = ({ onPressHandler, }: MoreActionsButtonProps) => { const { - theme: { colors, moreActionsButton, defaults }, + theme: { colors, moreActionsButton, defaults, variants }, } = useTheme(); + const [isDrawerVisible, setIsDrawerVisible] = useState(false); + const options: DrawerOption[] = [ + { + id: '1', + label: 'Noise Cancellation On', + icon: ( + + + + ), + onPress: () => {}, + }, + { + id: '2', + label: 'Start Closed Captions', + icon: ( + + + + ), + onPress: () => {}, + }, + { + id: '3', + label: 'Stats', + icon: ( + + + + ), + onPress: () => {}, + }, + { + id: '4', + label: 'Feedback', + icon: ( + + + + ), + onPress: () => {}, + }, + ]; - const [isPressed, setIsPressed] = useState(false); - const buttonColor = isPressed + const buttonColor = isDrawerVisible ? colors.buttonPrimaryDefault : colors.buttonSecondaryDefault; return ( { - // TODO: Implement PBE-5870 [Demo App] Component for "More" menu items if (onPressHandler) { onPressHandler(); } - setIsPressed(!isPressed); + setIsDrawerVisible(!isDrawerVisible); }} style={moreActionsButton} color={buttonColor} > + setIsDrawerVisible(false)} + options={options} + /> => { left, }, }, + floatingParticipantsView: { + topPosition: 47, + }, } as DeepPartial; }; From a3a95ca5dbde5c91618783a0fb16e526fd61f236 Mon Sep 17 00:00:00 2001 From: Kristian Martinoski Date: Sat, 2 Nov 2024 07:02:31 +0100 Subject: [PATCH 18/35] feat: add feedback flow --- .../react-native/dogfood/src/assets/Close.tsx | 19 ++ .../react-native/dogfood/src/assets/Star.tsx | 19 ++ .../dogfood/src/assets/feedbackLogo.png | Bin 0 -> 130347 bytes .../CallControlls/BottomControls.tsx | 2 - .../CallControlls/MoreActionsButton.tsx | 57 +++-- .../dogfood/src/components/FeedbackModal.tsx | 197 ++++++++++++++++++ .../dogfood/src/constants/index.ts | 1 + 7 files changed, 262 insertions(+), 33 deletions(-) create mode 100644 sample-apps/react-native/dogfood/src/assets/Close.tsx create mode 100644 sample-apps/react-native/dogfood/src/assets/Star.tsx create mode 100644 sample-apps/react-native/dogfood/src/assets/feedbackLogo.png create mode 100644 sample-apps/react-native/dogfood/src/components/FeedbackModal.tsx diff --git a/sample-apps/react-native/dogfood/src/assets/Close.tsx b/sample-apps/react-native/dogfood/src/assets/Close.tsx new file mode 100644 index 0000000000..192671469a --- /dev/null +++ b/sample-apps/react-native/dogfood/src/assets/Close.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { Svg, Path } from 'react-native-svg'; +import { ColorValue } from 'react-native/types'; + +type Props = { + color: ColorValue; + size: number; +}; + +const Close = ({ color, size }: Props) => ( + + + +); + +export default Close; diff --git a/sample-apps/react-native/dogfood/src/assets/Star.tsx b/sample-apps/react-native/dogfood/src/assets/Star.tsx new file mode 100644 index 0000000000..1ebde674e8 --- /dev/null +++ b/sample-apps/react-native/dogfood/src/assets/Star.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { Svg, Path } from 'react-native-svg'; +import { ColorValue } from 'react-native/types'; + +type Props = { + color: ColorValue; + size: number; +}; + +const Star = ({ color, size }: Props) => ( + + + +); + +export default Star; diff --git a/sample-apps/react-native/dogfood/src/assets/feedbackLogo.png b/sample-apps/react-native/dogfood/src/assets/feedbackLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..477432050bfd8a1cb0ba9e3c9a64f73dbc200814 GIT binary patch literal 130347 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

fB!tLyMGCPeH5VI&_@wfRR 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 - { const { - theme: { colors, moreActionsButton, defaults, variants }, + theme: { colors, variants, moreActionsButton, defaults }, } = useTheme(); const [isDrawerVisible, setIsDrawerVisible] = useState(false); + const [feedbackModalVisible, setFeedbackModalVisible] = useState(false); + const call = useCall(); + + const handleRating = async (rating: number) => { + await call + ?.submitFeedback(Math.min(Math.max(1, rating), 5), { + reason: '', + }) + .catch((err) => console.warn(`Failed to submit call feedback`, err)); + + setFeedbackModalVisible(false); + }; + const options: DrawerOption[] = [ { id: '1', - label: 'Noise Cancellation On', - icon: ( - - - - ), - onPress: () => {}, - }, - { - id: '2', - label: 'Start Closed Captions', - icon: ( - - - - ), - onPress: () => {}, - }, - { - id: '3', label: 'Stats', icon: ( @@ -74,7 +61,7 @@ export const MoreActionsButton = ({ onPress: () => {}, }, { - id: '4', + id: '2', label: 'Feedback', icon: ( @@ -84,7 +71,10 @@ export const MoreActionsButton = ({ /> ), - onPress: () => {}, + onPress: () => { + setIsDrawerVisible(false); + setFeedbackModalVisible(true); + }, }, ]; @@ -108,6 +98,11 @@ export const MoreActionsButton = ({ onClose={() => setIsDrawerVisible(false)} options={options} /> + setFeedbackModalVisible(false)} + onRating={handleRating} + /> void; + onRating: (rating: number) => void; +} + +const FeedbackModal: React.FC = ({ + visible, + onClose, + onRating, +}) => { + const styles = useStyles(); + const { + theme: { colors, variants }, + } = useTheme(); + const [selectedRating, setSelectedRating] = useState(null); + + const handleRatingPress = (rating: number) => { + setSelectedRating(rating); + onRating(rating); + }; + + return ( + + + + + + + + + + + + + + + We Value Your Feedback! + + Tell us about your video call experience. + + + + {[1, 2, 3, 4, 5].map((rating) => ( + handleRatingPress(rating)} + style={[styles.ratingButton]} + > + + = rating + ? colors.iconAlertSuccess + : colors.typeSecondary + } + size={68} + /> + + + ))} + + + + Very Bad + + + Very Good + + + + + + ); +}; + +const useStyles = () => { + const { + theme: { colors, variants }, + } = useTheme(); + return useMemo( + () => + StyleSheet.create({ + overlay: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + }, + modal: { + width: '90%', + backgroundColor: colors.sheetSecondary, + borderRadius: variants.borderRadiusSizes.lg, + alignItems: 'center', + paddingHorizontal: variants.spacingSizes.md, + paddingVertical: variants.spacingSizes.md, + maxWidth: FEEDBACK_MODAL_MAX_WIDTH, + }, + top: { + flex: 1, + marginBottom: variants.spacingSizes.lg, + flexDirection: 'row', + }, + closeButton: { + backgroundColor: colors.buttonSecondaryDefault, + borderRadius: variants.borderRadiusSizes.xl, + width: variants.roundButtonSizes.md, + height: variants.roundButtonSizes.md, + }, + topRight: { + flex: 1, + flexDirection: 'row', + justifyContent: 'flex-end', + }, + logo: { + width: 190, + height: 134, + marginBottom: variants.spacingSizes.md, + alignSelf: 'center', + }, + textContainer: { + maxWidth: 230, + textAlign: 'center', + }, + title: { + fontSize: 28, + marginBottom: variants.spacingSizes.sm, + textAlign: 'center', + color: 'white', + fontWeight: '600', + }, + subtitle: { + fontSize: 13, + textAlign: 'center', + color: colors.typeSecondary, + marginBottom: variants.spacingSizes.xl, + fontWeight: '600', + }, + ratingContainer: { + flexDirection: 'row', + justifyContent: 'center', + marginTop: variants.spacingSizes.md, + }, + ratingButton: { + paddingVertical: variants.spacingSizes.md, + }, + bottom: { + display: 'flex', + flexDirection: 'row', + marginTop: variants.spacingSizes.xl, + }, + left: { + flex: 1, + flexDirection: 'row', + alignItems: 'flex-start', + }, + right: { + flex: 1, + flexDirection: 'row', + justifyContent: 'flex-end', + }, + text: { + color: colors.typeSecondary, + fontSize: 13, + fontWeight: '500', + }, + }), + [variants, colors], + ); +}; + +export default FeedbackModal; diff --git a/sample-apps/react-native/dogfood/src/constants/index.ts b/sample-apps/react-native/dogfood/src/constants/index.ts index 27355178fd..acdf552504 100644 --- a/sample-apps/react-native/dogfood/src/constants/index.ts +++ b/sample-apps/react-native/dogfood/src/constants/index.ts @@ -2,6 +2,7 @@ export const BUTTON_HEIGHT = 50; export const INPUT_HEIGHT = 50; export const AVATAR_SIZE = 50; export const BOTTOM_CONTROLS_HEIGHT = 76; +export const FEEDBACK_MODAL_MAX_WIDTH = 385; export const Z_INDEX = { IN_BACK: 0, From d36c76afe5fcb9cabf2166a23353d4e26fb893cd Mon Sep 17 00:00:00 2001 From: Kristian Martinoski Date: Sat, 2 Nov 2024 07:07:30 +0100 Subject: [PATCH 19/35] fix: revert changes --- .../react-native/dogfood/src/assets/Close.tsx | 19 -- .../react-native/dogfood/src/assets/Star.tsx | 19 -- .../dogfood/src/assets/feedbackLogo.png | Bin 130347 -> 0 bytes .../CallControlls/BottomControls.tsx | 2 + .../CallControlls/MoreActionsButton.tsx | 56 ++--- .../dogfood/src/components/FeedbackModal.tsx | 197 ------------------ .../dogfood/src/constants/index.ts | 1 - 7 files changed, 33 insertions(+), 261 deletions(-) delete mode 100644 sample-apps/react-native/dogfood/src/assets/Close.tsx delete mode 100644 sample-apps/react-native/dogfood/src/assets/Star.tsx delete mode 100644 sample-apps/react-native/dogfood/src/assets/feedbackLogo.png delete mode 100644 sample-apps/react-native/dogfood/src/components/FeedbackModal.tsx diff --git a/sample-apps/react-native/dogfood/src/assets/Close.tsx b/sample-apps/react-native/dogfood/src/assets/Close.tsx deleted file mode 100644 index 192671469a..0000000000 --- a/sample-apps/react-native/dogfood/src/assets/Close.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import React from 'react'; -import { Svg, Path } from 'react-native-svg'; -import { ColorValue } from 'react-native/types'; - -type Props = { - color: ColorValue; - size: number; -}; - -const Close = ({ color, size }: Props) => ( - - - -); - -export default Close; diff --git a/sample-apps/react-native/dogfood/src/assets/Star.tsx b/sample-apps/react-native/dogfood/src/assets/Star.tsx deleted file mode 100644 index 1ebde674e8..0000000000 --- a/sample-apps/react-native/dogfood/src/assets/Star.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import React from 'react'; -import { Svg, Path } from 'react-native-svg'; -import { ColorValue } from 'react-native/types'; - -type Props = { - color: ColorValue; - size: number; -}; - -const Star = ({ color, size }: Props) => ( - - - -); - -export default Star; diff --git a/sample-apps/react-native/dogfood/src/assets/feedbackLogo.png b/sample-apps/react-native/dogfood/src/assets/feedbackLogo.png deleted file mode 100644 index 477432050bfd8a1cb0ba9e3c9a64f73dbc200814..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 130347 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

fB!tLyMGCPeH5VI&_@wfRR z;J_D9-()UG3L}}{l#r4NE08&f_;LygA};+N$fG#UnPQrMblOufr73;QP`OZg$4h`i zSD_VXO-dU4rTSEA*I}1_C*)G2zpioTC$f(S-^$|?Zis(cP(1)%wg_=o%p&RZR z&8Snd{E!f)O2D^<;SKoUWpDeAHFnGe@9x>W+ptFYbZ+g;+mSiV}*2g0}ahA^EcnB*%Gv7JVkw z`GQfO=+7E(2L9Rbx&*$`&Kf?~KII^hR3Bq^rfmHi9`(h`L(EXW+Mrr3>ms?r^mUJ zk)r}&j=XNDf4+*PTlX}@bu!PR;MKL^jhM$v14pH7EG&!OX?+k-ZtBnFiGy5Gklzp#y8K&9rht?lbgQy>6y)?gE6Y?#pT2#JfA-!Lyz6`B zvE?y-+Q_f{?Fv?gTOx2DEz&0cxO=sSC*skgQ87xq`|w%;AbYs!5ytL)YXyMpVbA_i zVWk{kZMB@EC;?+1EVejWSO-L`rKMUgmTn_5vi3E-;Yp&YhgSvh=l1-vsbUj$t zZBMQaU3XdTD&Vz3Xi_#n8nCueD3+37vmC&e>o319P4`pU*tF$*|J;S&+x!LV&N_s# z{YHwMrub9eb+|+y%!bk7b8f8wCX+`Ohs9<7>fCboc+VWS;dYO+mxVkUeYh>DlL|rl zGcz|AnD?dLs!$ig$}uaD>*I5b5bR^2r3 z5Uh!`?)scnIZYg}q6XWt>oNSg%vM3hnP)*HGfQTyB$kN~ME-rAgG8ND;J`gho&CTI z0#KL1R|;Xbxt?_^?;p2m*0=YBvjlMQ*gPNt=ni0)?K8K%vK&tg6a%oS1rUOgbz1nJ z#=znCK)KWo{r)W0PJcP3)SYN;0fWW+K#O-{(~;}3uyn9ez+1QMz}%K|aJZP-9dCLZ zhO;{{rQ@L91hO~cV|op6zTK1*CX@jn43jM)F5VV>w3!8JG0s;|dfi`}JBn3b{!@ zMHRklrqUoZS9TeVi%S7dAXp_J6=L9zgHj?Q3E&NV{7dWj#T~$}{G-Pv$o$0*l;>V< ztDfadttE+fr28LSImEwtUI|pgy3wH-p*Ptr(p73d~&a1}vTN^63Hg$3lH`k->PqnU^Q}Cec6xamIU> zsr4pG0nsGrONGtI5$=#iiWJtc*Fu(-%UV{lJD#W(#V(`!v32`bD~4~Nlgjb){ndNd zO~#%0CvuvS)sY@n=~QA}fC6Vp5K=zHB33zBC~L!&)=?R^RTQ%RRXvAo;w*b!d1SU32eYeEhZ=T*6uI zC>SJ2pe7sq;Jz{b!v|OKJ8x|V=4E>vTpnTn;s{^avyNLI?Bk|~8G8<_;j0hLVr6Aq zN6Te5D}iL$4h5nq6;0y0m?n|u0i$^*;h(}tO!pEPBQ0gxWR#7%QEmnxDnlGTbP1B2 zk}%Il!MUi$u2?;an+Hiz8;MP|^3YU(_cIf+4Dxv+C) zOWnj_mc%=ui%yHfAst^^!{jPC5vF(g3$Rii2Q#HC&FsGxxcPUne(>tTnzI^yRCQd* z>CqZimk$8~gxc5XobjXv`Cl+Md+j~lo>F`Gx{TQFco~xJI;ykGUbJNnEJx8`*1}B=y zbUvdgVro&Nrp=$M5+IF( zh@r-5$vUuAD1oO(*Jk5ix&Cr?fPT+>Gq)ZTlRg+S39Qdi+GP5=oqiuXWydZ{Nz7@$>7k;k|9@O!&Nds0!y-nl2;+Z(Np#{ErwKOYIN zSV(F+n|TV9t`q820FLCg!v>`EwE=Y&h}B-=z1b#W@vn_M(W=2b8D|=w1vX`oN68I@ z)UF`hnm%Me%IQYzpYG}irV1yOIdJV8LbPEMwpkS>lnJe;$G9}j+!6)?d7MQr%; zCDZ$|8G25dDF&V=dhX&knFn^f+V9U{ zZP$x1r39@M^MBX;dkptpQ64C590N(>si_@II}L}c7~T1QF@N}a^q>9nSlIFuOsR!N z<8+^zgapQzD14iL+mE;^N+4J|0k4E+S%TkW|8PwuowEC$o z@t)KJ6ED8y?fZK?T$EbH7sMCJYPeul>1>gOq1*_}B@Yavhrb6$>dC8ER zvI`2r{ug#%IEi&_w)NRh+q>X0Q5JEK14lA`$4lh4`G~Sg4aF|)wPHr+XWze!FFvrb z4`N?jUBQ3)u)mvKHl@JnsvS9Kcaq)=(32J}z4tjxg#Dl7G5byNoyVi3^2rf@d;aq8 zlFx;W)}?2c1!!4h)9|w>>_C(&spPvTA3H1QgK)}0WQ5~D47te_uzY&TwU(f z!g^VVxxs+yBR8xpK&iX9o*qY9Pe`E~%LSj4>PV#dvk{2XRF$Z*rMheVJrS51;zP?f z9aap4wrn{Q%bPC1ltQAVy`ZapMuAJ*zD!?3l^1j3C=vT`?$tf$VXgO+p77Cxly}x1Ia-^gzW{`@avAvXnjFbx{ zehC>Rqn;%2Q*lJo*E^uDtm!IOgi@-0KVm2tGMc+5jG;NuCL=? zz3(tSeOJrcNnKy+o3nuU`5XMp}4>}xW;!5>V zw4|N37}O6L5uT(VpB^)ixE@kYk6WWe@&0*qRDdTHU|x>PhufF#yafpb$N?aN0H3kq z6=koqKzL20jnD5$wTCDNz))DK1OyB6h17den8eSrOit&fqEulyD4TE-fB>m@45fiF zCk5Wo!y|n6|5?HVhd0K(<>ley_a7PK?`~PgYkuc2-uD%AWgj*CDUtxic_G#Rll+7v zA9NzsAFP|4z2<;FIN&oMR8N1i8)OB^iGS<>#aZP@4EO>mDBfKJT5{?#z{e%6`s9xf zia;+|4WwcqYtQCnF}Sqx*{qSs2Z_E%M~dm5Syb0URwoIWw8|qls@XRSo^{bE@hBNY zHc0umrLbUj*(I!%Lz^G{+!U|OCtA|s`lgQ2Sue$uLgL%rRe;N@k=lrt&}j0azI~wWMKH z0m`F^iov*9e_2h7S2y?wgGQCs_%G3sPWsM|ql2?yK|d}N3#?;GI0ee1ZrFwpNkI>w=8 z#==TzIht#TLADjU_SP0<$A$>ul>HQh^+?{Kc*qWcI{d~GS$R)r7 zNi7Pgf#8*u=-U9KWyC7e@Y=|ev} z2YNWX(5nx5tqQaTJ2;^7I#FpAgJ74iY9TR~yL(;&68L+r!z)IS-b|AcMnK#qsp=(_ zS=B}X#*;x5n02puid}jm!9#5Q>7oW70rWkS8z{eC8S7T33u7Ab9@D$ zaUh(cRGK2p{LUxg(BO1T$xsO@Z~h(d`a-j^ZhPLCnne<$$5DZq^Az_o?A zpKu9*18oi8fM#F_w94qnPg7oUqz5NW{@ePx_LF^%E5_=U`s~Y|Kb~kbHusPFXbSmy zB|q@_Wpt#IZ^0a$w#Qp4{J-81z>)Tp$MJ+6J=_(ZqadtOYEe*@Fiv{v(xN_36y<=t zmC2Su%aNl88uNlQRWQNBvL;hrIW@IA};$PaGDsiGsR%eeL-!d(xK zaa%Ds-E(k++xOL$$itN-vSjR`FAn$3Z>%M2mI>=VXa|E4oMqV5D=9OwtZRQ0jEPV5 zdyxGul{|ZoNnj8miI6D#wegeBm`_&$+*BSS{-ze$lB&EEYo&-9+!(Q-=QvLqMEhWw zdKS;pdRy1MkuA=>a9SP})8qZZuqXf{+1q<$ueW`r{^6dz!`;GLa{btLDb_NguwG*B z%wn{3I8$$|1e^Rs>E}rlPRefs=qbxId(LYyB|!&o#(4i#^>Y&dkqoS@K~11O(?%(i4C zVA}je??&qstyHrSld)Pi? zJUbV%9N+;}?Gs{2h5y&4A+3BN>vEWiWlr%Eu}rQk+Aoy5_^s>RH(gi_oXmobm~zS6 z_9S0(b-yZv%mOvzLK-oGi7>RLC?wi9aV(yl=qr z|6N?2oOzb-uD_-PSb}oX;@Q5Ih<6eY=m4#aFXLB#*Ksz1B8bU4ROao!kz;|++J8DA2~9@zU2Yd*2>)zi=v)O z4L>v$ASx;e99skfrQNJd3D`<|OMuVRGD4;feLb}SAlXQ^%-oV81*i-Y*m4Pu4cAY? z^b`uu{R}~9-G2fQ=B(n3Xh1^ZSyw2j{7U4Q6tLdn>OpYqEd;*_{Vnrgv&HdeSJP`; z2urGuC+btYdz_^nQkHPyfK7e9)Csy9$gFjR1<16CsG!KPbgJ%h%$M^IR}gfix$RHH z%KUkllA*N)jQ4#muE(x*EqOC?H~teM+0w9>4j%9dhVyB+d<^C$0~Z-W1?)hr(i{QL*gVI#1O-5vMJ!7GxGYeHKV%1!?@g4^KmY5Bb$tBpF@E^P zeLVmCIm~S8VYI?{ERmq{Jbm^{WnEozScj=X zP%fV=5I2xQe;!!XZ}HGVf(P$lmv72!Y3rqyJ;4V}8U&^Mb8|4~RZR7Q;-FG~1(rKV zEU07leIQ831sw**d=Pg8H+Fi%%wK&SjBAhmUZ*| z!Y4L?B!yY_Rgx*E<|iA4l|LSjv-`j*A-D7b2yHa(}_+x({hhZfiY7-``V&cv0P zUd#1)`>y@yWU0QrrzeglDy^4eb9;}_5|?8_I;rPiTAIPyt+n#;l^UG+S2-{^w;s~{ zvBa3_TiiA-?reMsH|LMxr#3mkysUn0`*RcrSs)XD7MVAdmI+HHd~kkXl4L$*`VbYx zzW#I_!eEL-IxM0wMq{UV<9g%l3W6*(`cJncHAJI*$s1`%v>8Pq>iTmVI$(=d*Byy= z79U-F5kE{ogfLEBw=s;%zv~T3Hr`4uQJ9v+Oi@gvfM1YVSxyT3CFy)5a%!iUgL)Tn zlkXd>`)b5*)?(`UzY1Ll$6jIl7?ium`*3+Izm)*90+~p(XGA`aS>o@N`hAQ)xRlFk$Sf8ISWiw1|U!;}hI zdIWUfOR>A`FPfTo-hM~JcUFFMSZYZt<<6Pk95v-3_uTbcLeAKWB}!09X8mR9R)Nd0 zxPqdp_wgf`UHLpFq*DSgvAp;d3!q2~ZIW(=$nO#k-65`wl-y5gtjj-0 z$kw2Yj7W)hQKmY4svQ#o-9R>Llp%s5x&_=2D&~@8|ng)bG1ah0&k%WI8OuMftNDPVR+nmS`Z4ie)!;edDSdRHXm2~n>d;N=RKdX{-Bj2RM3Izi|O$t|DF{Bh}2s2%~BI!O#0#2 zUH-O(M<$<5{E~~ifp4;DXhW0zRZ83L7%wfDmGu%HV1~1H^kqD9_rsWwP6@y~eX#Gg z>LF4t2G|ItPXQ=Gnz>9M2Q&pBkf12E3Q8rS6iNWpWSTK}NDdZKiV0zUbFzq(f3p6` zgC9ae+$w){#wc(n`<(vy0xMEqJ8kj^Vqo*RjMjFiy&HlG2jOTMi?lH#1;Kys5GXPq>CsO}!R(&AdW$#x|bCuw&iWO^CN$_V|rUUhO%xoF+-KoNO; zJtR2`D^o&y5Qi~~cTUxt&CnomRV1mr>2FDafog-AO7PU5*@E8Y^FVWF6%I`oa{$S; zxQ&9Rg%k`)#wp!X)TsYe8Y!ig3`Xw$@k&;*y&f`Je|b5MflkF5OdLG0au0TuPX?ga z8#H9cG?s#~aR`rrsR53gcH=Z)bMjcDcef~wrQSB*Su`jsEhd2hd1ppo+49H2*z^It z(Znitx5)yvpJ1k~1j%B@ZI$C*t#tz#MhzSz%aM_p+JeQTW3#)LS@^MQF5?}yFnO|7 z9i(R3Hds62-Z^}S%vVAg*OjQ6g&p{n8%cCuPJzi3)i*^2hZ1QI&F_+2MR7t9a^~6p zx(ze-m*vDV`~1T5maAgYvV?X@;HA=S%hzSMjN~3f(AG52D#Ec%`V_5m=R7 z6p4C{vTRv#8R&08wf@rcHks=o)q3c3jK*3Nkorle@L!|rWepUE~sM(||5JLewOH$4%Lb)vNe z@PYCyQc+1w^(mhdb=xaOnX_j+595o!2RP#eSR3p>dEFKrxd-&%r!c?uDV<4) zxHZU(!f;;6q}o2$?^DDr@le7qkghY~UaEs~{bjFs7*)p;jm_~yZZqQ$H2QlS1Dz6p zxpm9p!)v3p(ReV|XM|QUdvj0uULTR@S5?Vc3pVIbMz7hnZB*v+mqRy45&#h_tdbxl z2tr;*6FgY7rLjpc%WEuk-Y5W%@;DinE0>=X1503F-YEoJBs)Z^^Mpl$1`4S`UFtdL zt2s+_+18fIL446a69@tofqYyvZ{? zS@i#)JCs>o9b+&?Jw4ttJ9y^3vtVPlY2v2PRCPydru`#xxRaxgYbMEHgCHf6JDxR(kYoD-+J?x4ls{g z_N=l&gTf1;5sS5#_K!n61vuae=`Tl3-$Y*6O$&QvCiCGo$0UivCoz@j*7rH!5ppdF z<>A%_+I(qX5LlOD?sp0_1NPiERi2S?=O}@Uzc%sG)nZaUpZ&n zO42e+JySVFx%DDE=4sy-i&5ZOEbyA@R8rC5XEvRMxu^a(MlbslET8|D5L{|H>*>Iy z|E36Mj_k@cyUdGrONEPtbox1`^Ny#Bc90!plwmzRZjL8HeLPXM!Nj&(%vf z20AsHd@jFdp)kHK)Mb*29e$&aR8ZuBom4la zY-zSf)AOj#7ZPPf*jBP^IiZ&sxP)o2=p!u3!w3gLVkbZO zGs&|E2nX zZWk+h3c)fvw;i)j`X?B@`meG4bB;L8xqfv8|C>T2`0pQ zikf)L#z_rf95$){>z7BYiQ|df(L}B;_>(wBIwb(}a$G(f3>WT&w6#c(Xvo(AhrdP% z)z-g+k`(bomJO*ib*~n2C%*v!nDN)rsl2BEseQ4HsX&n2+*5;!ynfaoD*8kGoRfEs z_uQr(0}_LLsk*R$0QLqMhCQd$Mip3OrP2ol^%DZ)2CyLAfY9Y^WS@3*L8&zS zA4&gBr0Y8sXFwj9QZh0?g7jdJVY|NxFZolnf_Y={g<_tAtpj^IR-*o8o?R9hLH|jC zqg1_-7-(f;mqnE`1583ns5o2}NXKZEHlsJP)8kZ0H{160`IlnBisM65|7`Oj4x!h4 z8+2%ywrK|*g@u$^O!ZY=87WG+w<)#^&28EV-uX;SDM6dh0JdG?-&1wWsgKCFL9*>q zlAuuXr$6s8e~S;TE&zvbs$Wtd$-1lOUNLZ*IsZ+-EB*p&m%R<+xm}nn;Ub~Oy2A5UcI zl&rxlX|=a)cV(R*vEqp>0Fm`k3wJ*aYlMBz`fs5oFO>0=V`K`i+#|tQZk=Aj>H+ra zOangUFm*pA=;L&iA@drn^&|hA%6|fcsY3Z@O6AEFLHcxxJ*YYMn^1f?SpmI7{RGd6 zo^0w~XUZNvwO-54k%8mF{o64qiKeEF~0UR2faAc`(J3TKTE( z{q0Y|(YfjR%OsTxb}#%c;K1h)UZ0wv)H*x&E%BU-%eW5)a~NItZFsB`AG#e_-!B}L z2UU+$0L%W4XJF=OKaS^uGQ};0NhBjab=wWe#wAn8`nb8B5Ps@kFN4SjDj)?01>nWg>_2$ zm-9T(P%ei7DD!8&<*a}rDg^5*<+rF!#QJ3EkrEn_(jYPlLtcsnM~wwBhW}Y$Xb(pZ z&Q~P_Yc5jp9M-*Iy>W*mP|jT0ZkBgtCWHFXeAJJ-(KZ z!>RTQ8V~tCVl$r@Y$X+tR9@n3J-j^`Md4D1t6N=dJblv`)e4#?2nHhTvl<9;{jZ%Pe%QaVm~>`_1!K5&a8YO z6$csznN|t7^Dp}~z?8T57#~%Bc+4NbanLEWU~an3f`H&&Zg6;IA^;Ac5Je5|zDVm7 z>PiW$Pc}+zo{&U7Eq!E)_!I{x1r#83K`N~vJ0Sp)ZdR$ecw8PhjL793LFPP=V3}2? z_@(8{TlF}oH}-+xCl&1xH=<1pSV$LG5oMmE-XP)*6sxd1MR9SE9mz6U=4(LXqM^`E z6=qMA(e7erRfgc`ANg#vM8d0#k6jg#1RM~(!3YCFP*OJm5M+^Kna8@kQFF1*GSYn3 z?pEbR@DiDXUA-IY5Q}7j9pxg<+G6dm`XmZ56jVEv#}f^5`uS zUH5Z^VjZUaH~^oJdAW8>wV81n%x(pq`2EOCIX!l$+#q-G%OOBg^;WI3oZkg{@{eHc zqVK}EKZg@W3%gAs$Owvt_f#0_5Qp~Hq(@mjw^>e`_|K^_s&DTBs-5HG>ikP9(~QR+ z9T&hnWfsiy@BP5-F-TL&#@`p(!>yxy5SYOim74-)4 zxt5zRLW>s1&K+)D)ov7q9xr$q z1N(4bU)Gar!k~|+ylS5A0j)fisu;z8t_2f3i6Cz(3i5xcHVLflDlJJ|fVb#wnXqz+(_2RWef8S@82|ual%CF$PB8|C=zYD87pO42pE$jhS9?W*~ z-pn@4U-B<7dgXhu@`N8avEZ^8ebT4olog-X!gWnuU<6=k|2@&K=fGqdQaTF#I2bx@X&nFa_plloXqs48#`{LU4 z?HdJFw+K1O`tHSEl5ODlDJ^|$k=>G7cnh}d0|8DDd91Te!GMO{!T73S12;kda^-i| z4x(cPZAGfArf)(yYhIPltjeUlX6n@$j*Xk+KkL3QLVvbCo``y)PjR{aQV31m&QG&TiXO=`b+V%>8uxGt+2+8=#;79uUVpfUjz^1lW=;2O_)3X^%y_# z2eG{EsW>ULysv2M`$D&rkOJ~;O=#wW6t74=;+AkgHyMDI_?%aBJW(}04!3(ezycV5 z1`m9G8OK4V%z}CS_17=X3=bW4BYaZ}?)aOM2ui_lWVO`(r1#X3Jb@A=5w8pv#DO%K z@NTE8d4{nvRX6Sc5!Ud^i(P)m{Q`kCHpr{t68UW7aPG2hIH-r9K12zf(iHA8ALM?0 zc>@a{SpWo)hlan15ghWl>IPF(9fl^B4V19h&i!r5+blUmgXaBzi0(^YvE_F~-8%lqgxaQ4G zJ1#-*nQz1TU^}K%RLa9w2E5%H%wg`V7oqo}-^1#&eif@H3tSdN4_;n$(kTO&B@IV2cZG_}e~Z@+S~YJ)Kbc=a zWH)69a1ey|3PXl*zk%WvSu*kX^^svY2pJv|O4ETNQ5H>{i6clzCKx0vG)YP!3&m{D z6=YFXyP=_0`o7LM`t_hJux^sdGi4-h3OwktsB&_qg0r$+SiFNa6#gBg5Pn&NwNugZ z&h;4Vh}22s$^tM6a7luC%ZGq)^l8HaVpHQ3MsI%{N2@wa)>oqb!n7Oyl3_T=N6?Sp zGsX$vErA+|{;ZlkG`bPH)|7oJtQ!+=c|6ftxe>G+l?wozKx4l?MLj(}VlfTwWQ5PR zFSg(P9#(?@3^Yc_f#&_leco7;)#bZAI($Xol&2Jj+zjFy&pHshCrBkaG;+|h~CTiMFb^2*!MsV;tOT|T1B}E&3 zqGu5pUb%n>eo7n;sJS4jp(5ZZroc5ou&GH!>Ym!>qk&ihr@lj_WuxzLm}fTiMd|Ps z=(va=>Xb!BB88?iDBj&%F!{1r5K=u;kiN)BoIg%{V*?yq`NE`RZt52^s9*#}DNX_9 zge5NerUpiWLseYyd%&)4vyeO<2QHJrhBo-NN|jf?)$NdQZp$OWV7C6Po9j!|z?zXY zP{qx*=pJA*XG%ii@SyU;Vr{7(l+vtcmOGfCb9wjp*rii9Hi-zGJPG(oE@5EjFE3Au z=c9MkJIND#86oJDf`qL{(4kvEqc!w4pNrXxzXL0e{{isK7Mv1VJqjGWI{i(m zv7ir1rGa*Nnu<5q=Tpx*Ttciz{wWa`Sy5C^kCz*KszLa;zP*RT_^!o~2O7>@>qe&( zU@rByK2Q~q5DM_1=HLXY|8Bq=h1*U5Ew?!jPMR9Prp_Ep2TKg(lxHJfaln*%pAj1r zKtk*I%^H%M6S2qWK}DP>9)-`YrZw{^%;-TVB1}T0jOa4E(ouUN*|tD97p!}5oe96* zHRg{xFJhNFQIJ+F`#rb_HszA2dD#R}9VO~nuE%6mPe7W-M0Bn!Z0lWecgWwaE;w9w z85V@Ab)qS}ZJ>UdQg5N zf0|jt_)06q=OZ*!K#lBgwYim0RioIK%--zZ*k za=$#DsM49@_8y4yFS)!P@&wQ+1(;_pUVGc#t*-@OEiUrV>jYAcAPfv>EU#u=vmonPx; z_>+J{R!W4_O-6dYv$3yz1ew)JT9qXrU%;UKT&^4+h0#k3tsATWA@JAWj1iX4fliLW zB!&E7K^P?#^GXFJ!Bp@|aTrqJeEwmYqk&&Y7D|(ij2rw)$tA6rFr#9h!JzKNS*~)x z<$AfO|9ZIzi$Q43J4|6`;zBqM#yxXABz)bYwqA}6%PC0_3|@Si{!3&Cw(U<6XpZam z;c5Xg52KM%$|*;gs-7sENpEKR#aP*V5vFtkX!GMRdeZlUFa9nJj@*Rdp*xDf&7Bx5 zJ%}wUw-wWleH_^IYz(%Z1=?CzEO$H|>s!vpxHpR_WvJ-iqelr`q5zhB@aFt?t&4*G zD~P%26v@7nM~e;+#G<>5%|qhV;~Gpy-^I zho8DN0qm_k7KykOWYVglvOEz{!j0n>yH>T>nzy@!oRbUnh=(wNo2-N z)w(+{O793hE1rNGm z1L-5eihmc!g{6ovGwT6n`8O`U4aNFP7fLXN8nOmy+PZWH50`0;O&o!IDSlTDfr_cq zNERt?x=!NCK)Nj^Asf!L?fh9U!E*nxeaH2Qrg483P`e1H>f0G{Q5^sufvLKS>5>tc#*y^3?zjB>=uRbnv#G`8WcvuepJaES< zP5_LXVyAG5YJ&fc?*h7TmDMY;a~upcy{%Qpq`|1kE&1C zvHsP-BJgk97`_amoc^G3sCG8r$%i8oHay&(oV&Fua!}UVKMA?O&Y$MJ%pX*lRk>Mx zlJD~991CDV5XJt9BwsRu6BZ=z2YkY!Jw<;KJR0yBgg+aO6Xmu1FL^iDw-EAFVAKXw znT3D-8}Y7}1FZXjIsdYneUt!`&Gfh!P}#coE7gL=i|xd~*?LASr=Z25bc300}7c z1`(1E76ieAFA##?*1n+?t4xFvf9^XsMiG>S6gVbdHXkl*S8}c%z{&UmUW!1NiLWQ! z{kLF|fvl@+`y*K=(V3r!e`Vi^qu@A=++Rux2E4)PzF~Pt@}19EQ2(+%EU0sAP4TY< z|IWxrXO|res4`;sT`hVaz z6R89y+M9(0)t|W@vILmr439Yb(hRnTm|glCoFF>YtB%K`^|kvk%a=OsA*ihBolxN>T^#h3o#w**C>j2n-^z>@rNY277O&bv4%MX=0142FPW5Gfn_9d zg+%Td%|s$v3ECmRrHsm%mMEw%cAso4p?cN4|_hpk;T$>V6x!S>>yt~3>>`;jg{V|J=(&>Ox^6i zpt&=ijiWQu<8Y=lrHIPoi4K3IewO0J{U-ER3T{x&JG!J7_IRRNo;VqI9roS(AWjgS@@;K2=Gt^bv~o9z{FwGs?4T2n)1 zz#EBY|HzfHa_Yaz1_$!JR(|p=l>8Duasc8iP^p_d=0Q=QBr^5y&Q)Plfr;ZPa7q?l z(I+T8DBSa)jo&OP6bjcyZUZIaWtAIiRkmBf#YQieQPO#$;6@vHIF8Go^B<;L?JgD| zLnecyJmAc8n5VD}IEsTL2<6x>1y5nTEchu5EZaw2GfE2l2S7!3n8bUSjikHf?a05a zTjPOLSpW*k6s(aY52_uwW?3dgRm)4o^!Qw_I-UqU-=!*mY2_w-W-UP1ect7f#Su{D zuZzRRB*A6*IuaD0YGs2nK{X0!ErGp6X$&1ge4`M zA{QyJ0awn8SI#lup)gM}CWU3Ixa@jU7E0Q9a=DOY$y9T)qiRQTg$cg-)`lpr1|A4_ zgED27;GT0VLc(vG3DqYo&qWX1B?Zyt>I$-(+jse^-Y5>I;i}KF;2k;2u>Ngd6aq|d zx{^EKL;kAcXQuEBSxQv}i#)0F+B5;xUt~IAG<0N){-(Y^p2#rvXk6dmGd6jHUifaa zAli-uD6V*(1+a9};Rak#A5?vOYrTWENa=MPF};l|R|MS+FMPGbgFDUzrMBmhr{Hk-?m zBbM3py;b*T+ew^XXuOeuXRO^sNpkrMK#7b)xcQLx{>q9Gx zh_)1%a}$PxZJ66~5!QA*6Eiz51#dbRYg;bF^nmmYLgmcEg9=9lf(-3IPWCyVSza}L zOZumD-cs>OOp}lUUf$Ka$4l#FB~sk+L_V%U4(`G5$QN(|>68P^3$FS78}514ufhUC z5@1eFlX{W>vVNDq&U@2})&6Qw;em%$qV3GgDpjB8$6>FM$(-J-`6fG3i%Q>pnUy?gq-K@VH+ZB?!W0`&| zc>wav6!)BH)RY_f>_q8_=S^om8%w=8 zY)C3McP&1M-u>@K@1c)lZSj5#ODl5Y;_O5`RyJKT#!-x^~g?-*Xu9Yt-Ey5f1Z!-*@qKIryOA3{KcDYo_`fP&B_jdlwVbA1v*nr zmm6*C>XR}FCbd`W-`>|9O^G8^nELn<7ncCI`c{>o)#Y>@AcUd@Ga=Z@DJsc(>Jv1m zO+b(^D-m<5oJ4ITi4&bo)dPt{+|;WM<6w%b7Jt)_gBP9;L{Q_?zX@zBJjK5%F8|mh zb<)J57|C{!ITY#GflQre1I4U0(G~^-c~vL5e_15X0@;dOkwP|2YlO5g)l5U_KF3id zct4iSeSZz5bd05Brexa~k4t0pW{c^bK`lJ%$m^YvBj&&=9K^%2f2;U|0?05HRF3_( za=LZ@%>^hqDvQxhO@4H}YxjRLg1@M9Rv?ZC{g7h>kz*I;jFzuM*3cTJ!AMSc*N63Z~?$^5$6%DxHWI5aEE}W47|R0+GEXE@m_d z{c?J|=QCHXvKwje03k;R;i?gM31E+~Vs|I6U2n;P(G1WWtpSf*iR8>lQ(x)Ym!R@5 z8={3~X14-6H`eh)w7!U$+uwoV-G7R;^#$>v{73c09H5lXl=0h`iL&`eSYO@`?EVNw z4}AhNTQ9=wIj_gyyw_rB+w@4NuLt7&R~P@v^|*$b1|>lR)-%$)mWnS&0q{Y$!DVXQ zUM?-Fmj;#RUiSO-@kAA{91FQthaI9f{v1v)Jt~)@4tq2A6yp3`c7oq3Msh!HlQIC- z%1;Rhk3q>h{h`oxfzGVJft5uSoo5VN^)vkcPk9Kr z1`^)N%0>=bcnR3sQ)DuB$rl->XA6PcHIGRyMye>Xq0~}P)U`<}m|v$T#}$;)uaXS{ z5L73W1}!qe3Ep)C4yec}dtW#8ZguiJMq>S8&@QCdF{~4Rki1~`psWer>LSo`Wn|Gd zG9C7JC?Sa~6W|-s-gehV$?~BC&=i(KN9Uuge@pA-u-rXfgUk8={kk7k*F)O$R6X19 za;Cy{U7JJp)8n<9_?7E0k3Iw}+?UR$NUM{A&|xFdm8uXOrw=!?<0)7ioPiBP1)%F+ z`wLim7b744GTjugq zIgtH9pc%^eg0LKvNpT7yqQoEAmm%dJX?I)Z;H*hgPrbrDD;QRnQ| zCmVN|Z^FN|xQQJ4_L{J4Hb2^%<$DhX7wTF9PYJ>tL*xg%yh)`AR*_ma9`%zd=-_ zE2WvJgS)M!qH*TVcosGctsVtk`=5&`@d8{{cfTXSpe-cDko=Y3xgop;BRUM1xMcxH z?|DDgKl{(H<+@+Q=7rlZrLR4rgEtjCC60NF`g$r5^1PGr&rR_(0o4>)|51G0k_|Hd zmg|W7^<@-bVZnsY@0dS(qOOOO^r%=cm-;*IamrP0nsJqG9>fk%cTOh4O*U5EG>sNW zy`xFKvj7h4^?{R7WIwU6T*}}a#ASg%n4shs07TUBc1S@4%^3u)R)kOX_O z=nlxsW+nek;{eCA@GLIRVYEvCyrtL1V?xP6l}lJ;E-Af?TMr192mnDpi=mysP}WO1 zRbINS94MwpKaIeema6hD#2x+E{w3EFCBpW41FW6>25cC*?d{-4{sEEYvMY6I7tP1q z;ExhvEU%So+lC8Ry!Wp$*!@wQcELAd>5`wq`uyWCrLPfs@bW@Ptb}|K2`Ba5wU4&> zpHx0*V5`M*%HpK*Zua-o=U*28m6l7p!N;$^$?*s8}#Jt?%7aSr@F(q!2I$ zmPqq1EsWI<24nXzITwE!>EVQ>4p9GDi4##V;XOPwaW##ijC@wO(?fO~reJ97X*J z9trxZv_ujI<#S6+M19EUq;=i?#j^}CU-58=-a1#-%U+LsTqt)&meW6RdNN&|AB)Lr ztXTs{|7^ge1DodW;je<1cE^cyea{i4!dmnK1nVOJM6#lwE!)n)%GM`hBM_}E0DC@y zMsV3K)>Wh}e)T9whNFZZPRB7^U&4{QKLEPoyRr4ocVHmTT%6LQLnWv>^i|aTy2)R| zw^ScRi~mW}$oY{_Mgq;0A1UytwqRDWuACk(4_FU&kkb&Og%iI1vZO}^V6Lq9?yk3$ z8s)4P0s>;n%s7kiBp#~g9*0WFKKD5MrPMDw1#1Bo%r9Bc3Aqu2d>%*u2oonMFwjat zelmZ8^pr5kI3Pf=h+j^-+Va(56$fj7$$UxRX8n+=PsH_X!cex?*!V=5To{CP3k1{A z*=klm$d{4hGLiOIzjM#W;q;3Inxv<`QMm;?XZ&mMNTNKX^1>>A(r6VGHpw&GP${|a zaa%dFcpn|ECKyD`t~?xAO0kPyiyWn~f{ekOZX0&Z8aA#jrPz z4MF#Q09fAR-y1u7N1CW@C=AE#-om8DSXQpu@~_G!z-efmtHEec&cKfe8&Fs$Rr1zf zkJIg`JM1J%smxE$KUYC}J`M|v(rbD-{6z?A+)BK9nHTg->I@R z{w2b5OS_Zwqj-rEyksZJEgq`FTfX+c<`{H@gTDBk7Dn~-cy&D_S9>YS{#YKYUfoUs zA7|Jv>P&Ia7xlVJF=fQ!&si{w-$x1y$l+ViR7cT!N+AVGh>%odO+1`XT>bt4{j;8r z4MAmFJopcQw4~dn(EZI)Q++kbgdEQ&>bTKg)JC<#cr?V~{u{9Vg&)QIt$%?2_{3N< zClPB?DroN)3WT+kmxFqMr~7V-IPuQM;J+;$=ie$K>)&!8UDKC`pBg@7cSzVxZ5tVX0eVCt`lNIl9n zA`YfSeLs*Jv;+XK{mJd_7hnsb?W%ZWS;DrHbrC-!@JqRyKSW$Pp0sscPoE%E};0Axx;*Uk%8LCZU?}M35 zSl{tHYzQi+#}{w)@3Q=kja4OZ<~c>$Zx^}NMyWJKoWr6_Yq$L#Hhu9&u;u7YI9_Ti z;*>(7hyJ0yeM@%jrv8~5U>q->==i$&)BbaO>-1{9B+j0HS*^bujcQ;i;15Q_%W;zE zQ304Y-Sn}8bECui>o?z$7HBkq0HTC~cHzi{v2l3-LO@_O1LRKcoa}bi5DM4cIq>5e zQ^sq;1`VGE7O6i!%^iY03kV$uP@qCjo0ItNEMYwlCJ=yNc1oTl=!o(y!HEi+1T%;` zL8e2b{+z|I$Mx|)nP>lsrJqM`1C__pKGrpF!f!Xm0l-_#b& zlE&kD2f4Cu-Hipl3nz<4!_eb{@z10;B*ReweZu~jWO6z4f6Tv|_NatCCN_((+aOS1>E8WWT z^X|I>EJ05buceei>ODz>BtXigW4?`dJs-o3ay?`@oyqI5yR8RZKct?!`m=FH?WFiT zN4a*U%(J2Oh5NB`%`ai=J%5V+bOX@Irz7_QD-VQjss3wuC&f3CuYf#naYrSjL|n3u zx5*35>y_xJ1$+5gSucBae#+hBUe?*Hjy`-cjwiD8s2o#NB|I~HVC--SyML{sHR{NG zS62hN=~5e;0%yXT)F~3INFGY@6HDmLif0HeKfZlA@E=9)m_RBy@j+zV2C2Oou)_8r zcnF{z=DG%w9AwfRSkAQ~uANnBiDS1E<(R!XgdIUS$i-X!__iV$5xI;R|FUA8(XG0Qt|9SoQMn*gG?8M z!ni8$wr(~0g0DA-LbyV)NGpgch)4D@-7ljh0&J|(%px0{kk9q^UNLJrnCqc8fU{nf zyjSiXcN=^xP_;~N1ui_utd~~SYcK6@UDqr?rTL@!ogTaa*!ShQmSr8}c&#fBPU2tj zX1_lRKK(h^Fto5I?QZKk(N&^n>gZ4U)e2iPV@{^XjvtKjk!{bF3$q} z>d#?BGnmrJp>leh$B6-pZLjKCxHs`l$}J%ali`~92OZ;(=~Mj9R=%6td&=cRrJSqI zzqHH0{58%W!%3t^?Ye>C!t$N90x+OQSo~N?5cys!5mn<=T{1%JkKY{OcdlxMX8@42 zIF;%5^kL8bPh5L!@(rIa>EAtb6o>m$?wZftQ7$I0R^E{dC(3JbAlGfORP@pUrNdGP z96T6Nn$w2Uzu;`yTwa@q;<#nmgSY^M>t$Kg6({Q?a2NFv^jrzD3@;?7RGZ46@+R{o z*B}P%D9WT+B6!ht3te6$@+8Xc7QV9M58rm2XzQ^2`lJ9><#T;5;8{^VB(f>}+4||F z%fh1(s6df+dfZx*%XmxcmSBNY`mJF^X|r#%xJhGw>8K5$$=xw>X_BSLzRpcT0EpU76k^iAm*8Wo`D@Ez~L zX}A5>^eCf~MP;8ZZ-FXF^M@3~T1@09)kmAaX4W4!r>*5nTYS!|`L8;js2+(|H}{Op zNf~T{mDfX#mcD?KNRJx8+%zhW)Mo)6;r`gaaH4)~`Q`CJ zLF;S2StzE*i|L+ndc3;v%&ZTs0j6C_5%%TksTbC31w>g)i_6VCcC(K>`?8!?y6bXq zDXvt1b@d^#9lfW%HHBw%2S$RnpZj90_qSlf(0Okt+Sp9@%l@RTgU3R;9h%~6RQfzw zI@XO5wEK8G#GzaN6uWNw4NU1I(CXnrewby3vhGuTRkv9n%Z2|gJd^X|fkbye%c*=J z%5UXlWL|wdQLoB=X}uirIEbf6{wpWzcp^)W8o-=ce&`nP>PQ1g0wbyPrP2s2E;R-9 zObX}-Oyr)0a(4I}Y`U0VfUOz^d+1DD?(BL(!J^OY+b1wTQZ=z5j)6j&im8?*Z+ zfigS)l&E`ux4A4c`>c>y^Q`Nj{5w3Xte1T=J!L21uhw(yb*%ETyACW9xvBlRx8bies;z!Ivb7t5+|7+HGsM0)=xe}tE)Hr z0!!ecC5HGTzcx==jOq;;Qc*)#$$VVV*^BbCQi`m=8Z40Nd9Xt|yp1&i02(-?04UT! z?HmFdh`f_m&fbay1-{vV8Cm9}1uUw2#npr~2uV2wpv40sR_{UDqTB>T?FLvtV-M#K zcWZ}-t$=M(^go0xv!6t4bDDR9B8SvVf!MdoHdF&CYED@7h53 zkC#*e%V+*H@SNWOo%2S_%PykjT6sZ<6sA*cc(Wyr(`C z^TRmF^r!*MD?j+bqy6jeB=i>6v=7 zmNAfuD~vY)r5YrPGI^yAmk$T5C=8?5=#i=~X^oX@Ui}~eVLj`-1>h2y^64`AdXa$2 zffP{}!BIS}PK^w30~n6#h4l?Jsl2sO6R)+DlaNYNwX^0QG2pR%#RAo;Ji?Ogg`6r% zQyCk|!z=4WbM%Ypaa1F6I|WqMZLqlqF*{VgNJAR|gb3yalF2c&(x!7=2nyWAPM(_)M9ivwjmc8fx5A-hn9`tuU z2fhA$!3Xv6D@}Ei1$mlLn2?pz_LtGUy?{=jQm47Hv>*K&|2z7r9rRP0oQCV5eg6=* zBaj_idw&^0919r)U^IX(lutv(r{mUqOPR1bz0xcB^Dj#(r^m}9irn>(wZOdhWFAjs z=~3H7UJ;FM^<)Xu z(Yg(S#(;VjnRK5ys2IyfEYj6wirX-bJ`i3&D6HYj6N78(MeLB5d`hW=5@kHRhThza zIi84|04{xvxZVT)|F`!h@Rl6qedxdXoV(4c8O>-zAV5OcNC*RFUuD2RUT|XKIF21Z z$8qxVi?jG8abi1hUdYSlIF5NqoESSXv11#@#w$2rFc<+60*ugtq**j0jrL`>d*{x~ zUC!yQ*GpCPSJhutcb~a4bMKw{OLtCp)mL9tSJ(3IueSP`YYtm~VpbMQO*9Rmq*hG* zCzL((^a+TAzn2>{&(;rV3MHDIl>6&G76+dnmkqw_TyA*H+mMQj+mxSIP|k*yp@IgKGyRj9j_hqCTG+)l%NuReDK;tGNBKYjEb z>^%AzoV?<_h&V@_eiU-Gm}aQ@;I4f^*E;JXl5NelFD}_Z#uJa32QSt9ON(IYcCTu8 zbF1d<=W}}^jf>hU4NgA$fZTp9imgCoZUU*g3T2)Ub;n$j9RY0?(OsCNTiehVs?p&k z8!wL2fp8+Y<%#yZ()pzdzz{fTGY(L1+YM6KB-s0uA!u z5)vA=$(f~7v6`)LJ-3yv)R%U9ZHN)I9@{Takj~zHUJ_Xy)b|h;V-L#+*F^-1mvEAx z^2d-p)X&<8++u=()<;rV>4dH4zX~-5ZEbT!8YM94u5wfu!YJH)GUZWN-&79wG3C}g zjki2G^@l#ze2U@RwA!9X)p=2EPm~fOS?8-N5$dQ%Nmq+Q6G}}o)jibEc!AL}aPW^I zPaUz_9{T)U5o&*Yer_EKbY8`KS=sekTuR7>TY%lSRDaih53srdar|o-@?%7bW=E|X3e;pq!frokVH1)g5Nh@r?Ni*sDZz694uZKR9XVB3rH?)f zc{c5DtcS9Zq%y}OAqJ9KkDQiGct}};IO;T!2e$UC1oQ`i0AG>KW0Sf9>gIsHI~}K$ z9fYjaLLAw$lseBWYyu%XdMq9M>!b#3#pXbh=NhD~7})aDp*6BH)d_2!3ypnB1r2MJ zKSdc;UQiNh$f;H!Bq^ruhXB>+e?5)oVBCtWHRMQQc$qrAN5x%SRP!&T$=`Y;J2S&U zW-*Vf=V4kym2T+*1H zfxP-n80UX@+24gY^E3v}{4sFiUdUrP!AMuCJrElsG6a(RI?ZH5#s^>L&k@R&vb1pY ze$1SD2)Jw$?QMFYQH)v~{nNT(@R2_5BaX_OMjT<-O`lz+;E5X@{JdY~b`aAQtNEA3 zZ+SFiM%u&j!yEaK(C7|a09;gpdDq83{`gDZ`gfi>z2%x~8oN^K3(1rUN-m&+sh#Vk zVIXy;>ptIbBCEr#UmhLG)C8_pS8oJwB~o{I(rq~cg`%y%ImA|=S$5g-DaisT6P`#3 zruB24EuDuKjUq1f!#Rnyq?*p2$0SiTe!V5q)D1H4Qrcyw zPNHnwOGj5d#Y8sKr0QxdtP@Ad3@L-+%qS<8Njd+rJb%2{)~#3>sTTK?G?9>9z4eeZ zD<%Q6OQtm>u734u@v^k#_fOsr`QS(M5B%ji&DOIyN#~x=y+(_yt1lFXBR89m04)r5 zB0?b_7L?nchjja2t!@iz^!$DdpZWyk$@`F<+K*x=UD8D#E`0ALgwXru^hw5#bRFY# zgdGcC#py^eC&$^N5GTLXd@YT4tAox;^hmzFRl)7P%_^5$ab`*J`#wJv3I=OreMg7+%W#O6HBx z?$NSJS^AiJI>cf#qx#v1n5MA$X{^r>b8-qyXD=iyV&*=Ym(PL3E8V)qlvtMqg$NvZ zITi6EUTR^BHO*ENNheP$0#Ij{&PIE+zka{kUBI%ea&C6CevtfOWkr)8S!GAqq|v;3 zhkbbsQbPI@1{$&RZhVk#>j*UF_R>VC-`eVJ^>=lfCmHpiWl*v_%hV&TE`ih)Qx7Vc z^z;g*r-v8}6LM^4mA~UmZ#M)$&#}}56Hr7F^@{P*m7Xm<<8-zOJBE;qIF61QHqAe)*6_I?Y-`CqY9Kyvnp+^Y3844?TlviS!g zSC7}Hn@oyOIY5g$_17rNafWo^QAC^r77pZ9U2R@Zht8PhhXsA7aIV|xch7p<8m2{` zApceSUk=RhcqYk7WyO_Dzkmybi#{`a=FGF78g1QU2qyRLi%iQ5(GWz6GA2QKKM8As zpyvg4X$ykZ=|&;*5HsOKN)!l9(43xFAE9UXDJU_uhrSK@l6q)gnt7U(TvWdz@G$Lp z)_|}>Hw=r8TG(&Tgw+l<&yW_8v4>*Oe9yHYye)t=p_W{O&Nl>X%Qj6DQKv7JTDW9V zzY7RHH4;r8=;*KlbYeDk*y<5|dh8U@DGt`G0aY#qVb?-Ep&2=FViwM`wT|)#&+o|< z47X0HmE$$ZD>e--_rENUKqCvSq_l>E8WzhkFVwa~W%{djM=UKM`NnVLo%#{5tHxV~ zs$2cI_shLT*`kLa$%nyKcE27G9Z@V6+V%n<{~N#P{lLm8404O6Ja!lG^k_4^qe z2sP(CME$2v?!to>>ylvVA9>zz`iO%yJ%SQ1X_dK} zWDx7J({|`@8!4PLN@bJQ^A?@_6|m#4WNRHkNb^tq-Z_xhXiu}?<)tn^lC11kmSF3A zd(g5~lUEau`tXt3L3>(^lRQgncn197})> zk=K7@r8r$lUSOPe=+SPlO)O_2>Mw7`&HCKvl8_)OQo|C zr^B+c@qVdl>&wFjmas|2t@h%gghlC{dM}zfw5PGDxiZ>9Eov*YbmFOBmS~2B^SL27 z(nd1M5O+oXeSB1BvH4Z?LF#$|^R7%%;BZLl;mCtLd;I}blkUn-T8T+co(5(In3_`l ziewh;!Z^)`5X-M~fqJF5CYXA0j?yWeVR4WxJ8}z$IP`ho$mepAF&cU4rl0GqeC1HK z-241QS6P9n!4x9a0EKmP`*lG6mtOb2+`4%h$-)D`@jpd!;_iGn{XVr=NR^Qg0f6V8 zgGXKz$D(e%3K0`x;US2#4^@3kfv)d{&J8kdj*R=xwTx@1@yT(&XmPjvINbtz1^J-d zAC_1!b>ON!zg=E{?TIwj!{%w(juQue_rx`?c>_%Mp?4Hl5>AJ!=UJMLSyZ%351AU0 zLON7I$(CD&1btW1>D!q%&2~KC$&4?s<6X~Rw8@8X(x{(}T35}SIZ1WZ#8?wJputre ze8mfwc#3e#+00|vtly$$q72Pq@`HF-X?GrimKT>@yUa+3afq5xZ;DY((A>U7|JI`; z&Ag%Zck4tYix4W1eKebjm=?(*ZBF8J!{QB3QwaNs^lEZAeW>7zj&N_ds07n;H|meN zKa~$`OwZ+gfAI{NdYs&9mw%Oyv&wpzDPk%0vzo1lWRqaJmdkVuapWt&gTDhg?$G9T zwQRKcg*qM}To3I8K?p>g56o;scE#&};xAikiv*YB-CPotx}*rVEMV_rMq`RFh!kf1h^~s++XobBCe0aD6PK9bu+5K^+e% z?Cpu_Iq5~qmwXNv5bI)h-t03U{jm5eulOk`rU$w-(2-k8QuGjd4f@$fYd7(BL@jay zyMOQWZoNG#<1Rbsa02RK@s6$yx8nk0T@cI%@BGw>>)!vPUtHa`_wB{K8S2s>0=4-Cq>CdYhLTL! zoty+Q@QB7r=W5|dCEyy8YJ~*S<4xJ0<&FmYgvKvhKP!ovcJlS(lDUs|TvDgg#O0|i z(vhQ)xCtj;0)i4ASudKg{gf)>R}qx@ozl&sJax_O%;C9rpOIvSu%4A(J26^QE^K|) zD_2B|l6`B#d|8*VA`WS(CNgYdC5azS+B}5@u+!^42I?{=>92Vl@|=J%)JUhE2o;9} z6Q{3y>4YRS|Am#IgVSe_%3*apq_J>U(<;VkHUCm((vHjAD{^Uu!|5t=l=JGup}YgS z=T~zgdj>q1eC0?d*CAMCiqqp4`vb3AL8_rkn{V(%}^<*>Xpx5w%q&l znfnf58ae`DyzLCC;~^8ZJrUIQL~0j}S}yw|0W9ckV9S5A6PX1!T+=`M+{Z}^fc2`>54GGwk{tzX4KhsHtX z$u;^D38y!*b~3V`tC0d5t}3pf<9-brmbDsZ4rfhZ?3!TlBdbmel||ADCDdXQsq@*@f!Kb~R17Sa-@0q11qqu9+rT~qO$}RUQOwozV zojr`DU9U#O#e%2^=e6I4asDTY{Zkj8$gP{7$LN{ck(~NQ{+?D#i@61F87SJ+0mggd z?f?^G{=xjq>sj89)=}TbpIi6c_7HYGtiv(-T-{V32MK?gB=1#{OX%&1l5$ihOEa=P zky0&X-tZx?0qoji-4M*vM@PSx>^}Qb*>G-KnFl3_tk`(7OjIwp<_+%FMHx&FuA#}8 zM3Ywu``y!_S(5+?*Pp`L;=&;ZB)ob8;zqU>5`KzU-PH?yGvd;rA zSrD$6AheGX5-|O+c^}fOp6B}Js@`(>DDCvo7whI-LOX0(t7(|*irK@Q*|Sxa$Ut@;}`8 zL%{M0;Q0NRKKcc$K6ghxy#7@F-qhSp4d-1Cx4r-?yIzBc$smt@8TF7090Cyt$o2DV zofb`5uDg~VT_WHw7EZEm4^@3Uq*VQ9agpNFxWHI91oQEq`=O_<`Hx@x zN`Cncos*I+4Mk^|Sbp_F%x@RF(eeVUV(Yai*92>0c45X`kEQ$T}5P|{Lw zQtj)hs2!7#PEznSac$(CkeX{l&jk?sKlG$eQ6WQdU}E&ak;GlZAnZf!k!fAq(!)4U3HRG zO~rLy(r35ZLrD}?ze3jKlJarsyp+ZsrEV)~HJU0{tXHL1f#?4&=GMyvSk3>Cf7DE!K7!SwcVX)27crW@FSn?l0X0etX7^&txBLX= z2U`&_0Y)pp$$M-!tHB3f?>P5R9hBhP3}4-s0U1|sBOKG-YgaWwTb|yd7WkxNSxp}z zI`bm7jKR{~xWHI91hc@@vj;wyKL3^PsB>JcD0g~)$-bcqbY5S1583F$sm0TjDaXQB z69=bdx8AkOSafIV^z04xCDAA}L?ab7>1Je1JrFkOluq&*id{`UOPEVIO)yCwO_NsfEX|bLkKk=59d5I>*#DtnRuww{YH! z(TzU=#d&l1tKPqylzzG>q3%`DN`#pGY{GBq5m&Su{>e17)7w#ARZzF9qX9Z)m2I zkA%h(>pDQcSU_^f+S&`CXQ_)i(YB%6e62~gjjgu{Q;nRYG8G}Lw-!=jYA8n>KM6T= z6$W~EybM|GdzohS;+{&iQ$H#4Mm9P2D3bd>hVfJPLQ-*b|2mc*}uwDVch%lw|1zA097|V0}R*XO8}7AxGsISwiP} z<5Z67ugYiJjao{|JuQVIG=dN{#YvGu-e>O zrBkI@pD(JP2@E+gmR3P@3Ta=PbUXLf^O10XWvPtqQ>7r8eZjyriN z0J!^s^3Npfyf?&zYbAt}_ptMekT$9H2)aLNo$vM0k}&U1&<23!UmpmMTceE0Mw!#; zG@GXbE@3t#U8E zyv5>a45o_}kwx_N7DLs!y15+PFrB1}mJN}vU~uH?5V!wVjGy>gPA*sNJeAI`Xn7Bf z#^2YYIAPoLa?p*FU}T+Wi)_fA_#_7Mg6*9g5wUI|j~AoB4uf;+nuNc7^?gJJBMs>j zenRP9b9#emtd#2GA&XVynL6Rj7}@Ht@C&*n0WFt|K<0vdiw5~6jB12Dbks# z&fM-`s?MGxqLRod&|$vvkCHn-S@c3M_oD76bYCqTKiY}V{zOocXGk)vG}SuEGrDQl ze~E06C*vlFpCKI5kh`+OCPYh;FoqN-w1cnGuSva4m{I8_@mK_b{7Q>#qxnv>Jm@dU zUwVGEOSmbyvdE=McOtDkuH%yCSwM&{eZRWgQknAoSm}X3T>w*_=yOWzIo;=`WyxG5 zuykAbs`N|CUqa7|EC^ji1S=9Lr6!K4B8jOYmxM&>YgrLZC?aV{WtI|MRoL=Wony~n zJRar4<4Jk`cvb(axXaDeGg(cikmNKT(ms@J#OV{5`r2yx7{`#ES~reAoH^T?hg$zDO6`z zc1Ws&G{jR@BuNNKtWGsaD(RKl53^YaIZ^`uAL?Hr>@-tovSo$Qqztt_V~r9{`89+F z-7I8o+NryKR!dfU2`fEZc`pMQRdhh+w9P z-?+3YYD=SSk)&2iLN<{Rf;ldUV@)inU;PKAZ+PfV%x>F>;ZUgUH>xz3+Y@Dk@X~sv zuXEkWbB|zf$1h@Z@YBdfOXTG`gpig8hp-txZzom1V=J6wbaw^S)g?IT*v8{kEIsnS z`*mCq5t|K1@5%>4$O1l6M{1C|t=j|%yZ&uL_B#!H_1txq1D{ejy@+pl_a-H}vpMGD=^>#c|s z44F}sNL|(hgS=58n&qG@Ym~q+WXAUyVwj1fNg$*_i%F|o)k&5P6;SgIt0y+pS?jB% zXk<#6sVq7@zM4VP*!-2&t*p~ZRMTJ~{Q@L!NnTdZSQFlQKhipHn_CnyHL`Fb3ti}j z=VcuF=uAOd5@Cl2IoXGXRe5O0BAhLvEDB!hq*-rN$9med!6Hz!dshM z0^EoXSbFj^*m3P`I8~ih5fO38K^*;j{sF7zS-T&6?rKHT4M^B?<>2@`?rg+NTwL4G zrpMJ42yc2iVIL1!83RaCs;f`oB4J$;%-jC!M^9h>Z{Pn*BV6_7I=?l^$rQ^R#}a`u$YD=6S5WILQNX4;{(`!CZ^XJdROYr(Scn+SB|f33Dwi zZz1WNX3`!LQfT>_!b{?I{Tw-K_4mpM$+5>Ulq==@%QD|Z^$}9-eMw?0j*>im5>rn< z0P*^H^DaMtz^FC;Pb9vt=ydFqTJls2m^mlw*+<~+fR?Ol44`O!5 z%dk9i1tKCYDHPLiPCNj+eN*5*_+-G(@>jp1Hkylz>vFrm*Y>z+Q5{>k!FnpWEX?y}>`x4btCO6akYnkbO`(@|M-UQNE&)`T}P5J`c%d`QLC@Z17g*=hE^DvX#>i z$BsZeau?(`{s`iMKSXxqD@ad04OtF{Gp)1Ef5~|O_6JzgI|$K5UIcDMH{BhvvNDft zID_%tHzE`3wrP)uSbNML&PRcN9>rq8PUu>{-1bAX$hNt6k#XI0{Inm^E5~!|<@EG) z*}sm{H2)i`T{fWG>(68Uq5p=9gmr1bEO6+PpIo{AmiPRKc;T+k%fZyJ(LqSMeUUKz zb}2^s>H0WDp*miA+KSurXmaF4MmEAVCb? zw5m9f;H9rk>Q zesWyeJnt&tA$`ZtU zKKz{ziidEA;bDdHt7u=^rJ_i_aJn(l&G9`;{b)%kJ z{n2X^y+ypppC(E=jP=YCwlz?CRv&A3)H*e>5_&5lSwAyzujNpaRgx{z%4=!mqZE9; z!X6EQgr1j*MQ9>uYnb-5ftu z+Y*^!aFq{MouotZ#W~{(Cm|M}&A-Tp)faiLKO5)6;;TzYmzP!gCA^^TTQb*NefIeY z*(^T@+*4h_gmnmKbwq+G>yi&g+*Vf?u=2GZ!?tHHYTpuZDdD-VV(UX6!bQRI0_5WU z>YCUD8vO;(Y$tU4PsycQ*Qh-G4M93-(R!(SBR=rWg$gGed9(i|pib|Rb=P0~$m|g; z4vyd=V!abg-1*UuE=?~!_g9i^v}!DSx=@rI6+<%38_g_tx=*INzh(uuW03)JBiX_r zokA%9OHS&r0AKhC5i{kJxN-3{NhbKT>csduRI)9MO+pnZhBS+gbpBhLiId0BVKvzj zB)#?fvy(;Log8akyB)9VMxLK*J7{_>PZGvtmlKyz&ml=UtI1?R`zpd_NM4qKZs}uf z+e5bolFe;?p!8&VWAaQ9L!&1%a@O9HCAq7}pLED(O$N1$B8izpDk<4CL^4x;86lC9 z+)KdST1*Ch)phdN0St1BW${UQNr z@k&Mx9l}c|Zb{N6m~gc2$YMU`DJ=czKgP~Se;ot4iin8wiYNaF3rGGC+ZP|i1;_lp z{Hy9jb?uTlN(TU@K04%5%jge0Uz_2BTZbEZCA=S%5@--mQupno>p7Tecs$c>zNC7; z2t066EC0GDm<68vr+@jgTTVUo2UUk(WnlfUyJ(>xFoakN+fVP4X?2YH*AOZ~)HqPq zDAcCh+A0P|M=2>SasuWP$RegixlT|o1Oh!RM(eNd3t6k*BSfj0cAJD!D2QMzQ$ z5KT0RnPiWvCS9z#KLR;_oDDC&-l3)@}I_a)Ap@;Pzg!_zE{z;QA z{a?LcMp{<6nY0OF zK@Qb#Hf9JVu|{SjEM2_AEC>R(U#(-Mw8>{y)l>D(l1J_-7xfgA*6V^S%e+d*X;pWn zGqct0EF|OZ$_kIa_5PU_UBXW;UB5Ph>&C^U+xI-KyGuR^ien^C-}mpZ?XLeD)635w zBI3Lt{{T!D?kT5dOzr=fauJ$&vc}a&< zN+oAVCu{X|2$lZz{VC$8=MmaN;;2a!n(jKRPLJ8A(HV-a313az1R=MYuu4}qBy2)T zh$RW*)-`HbtljGLOOhthcqS6g(JN>k&`XCbH~%Eqit6^hP^N=3n!eDZDc*HjRsjHvfzm%Bx7yV z!`PWi90{QWv1XbfZD)AfB8x7GBny$;)$P{Q6{hZF>FQwV%;#o~KlYFC+`~%)wV#{$ zfXPLQm66r_A{7TM2eiI%kUNcVX_iFW`cqI9m3^mv} z>JRLKQ(Z_?0J5^t79vyhGgFH%$j0pM7lLsvLeMkyTA;&u2$VZV(nLirO6#LUO{8>3 zN)l=|{07WIAg#yRbXus45CFS4zz|wZQ>9^v+BVee3u(=gBUgF4_@HT1q!hKIS%_46le{*HObFEwnFyRmlhy<4g(|`g zUlLsEMjy&$JCYO?>BLjVr3woCFU7r=ei=)@BgDQ`B`>p8k!6ohuPl5r8z*<~eD?9% zkNwZT^H4!;w_S0=^~>1y)5*4Nstnbu-N)mxIyoq_pTX2!=`ZW_d8DWAy9;Z)I$(!4 zGD^2^A&*_*YaPO)Pg((auQx{=oBt8HVnZm@c0LQ_~Tdo$3OV#l`U8PW8K%7EpJM) zkW?MBunn_j-XIcigpzKWQ(0XS_)qh&6qN8v3K;9AB`2IREr>BjFlAhkN=fvBhA%Ii z#0a+r)Cs1mw<`x};x?T&6Hdowks>o?flyDqMUzgm(DjE&54Wc%Z3ujwKZU4&DOt0L zBjr9dd80DTt$(1NRNDIBkVQ+U6}Tj&hQ7;Ycv&Y8hBRuW(n$;@k*q#D?uLvZA>4CP zU7k$0%7%WaO`+T>c^HG_>tZ}Qlt2BUsfGDRmy@{z|NK9HYP_w~Tl?*#JS<*CaM5z!mPG@7SAX_e1~lZUbOi9f{3b>D;Y zj+6J~to97NADR?a{cEXXA>wI1Dv5uWcEr`~wo&vM*!YE7m|9sc&GC?FW~L9BRpd!_ z8`c3f6v50PpZSqL_Y=GR)2D94+|EC5hI37yn5jLX)P9#mM^(&MkOJlepGr+dh_q#s zSTU+g?M7cVy{2TYSrT*^7OttzoF3$ELu9AS{#L2`kKhLuTe$fWZ<4Jf=>Fcc651&- zx#sC4B{2%ALQah~CLlnMa^#;#=e4@F5+NOF>2N!z=1QPpA=Hm*2&O|I8+$s^aMEcQ z>S}HCEot;*RyaE?R(z}sy^#DXb@GHSBu;+2FV_l37QIm+{ebznf0C{|lvkZYL##f$ zk`15SvV7v8Sjmp;`r3az_{5!eE>mr(`uzZSq;mMKfl$Ytp?WW+I~^W3uT?b3T!^^! zh22a9{GE<~HUX|4SBC4zj33iUx_UyLsoQBW{>6OV)#VfU7yBn5p88`XgDsf8{M8V< zZb7#9HNf^8F&b_~L_{lAawFO4gY|vUZxsFT;a|emy|2ZYEicCTLtdDlzC&G#FiDht z73S9`-)LJzH{Ed3K|fTvI^0H(jWSfnLlz5sGCfU88FZ?)KE*iu4XgufG=frQUCES1a+lOF~(XOdz(K9g686BuQW3y~d}UOu~jd2a5pxf4%5v^1D~>au5! zpFHvFe{V5W8qX>fXV4$nVCD@&HF3QpKt(?0Lq6ltSj}x!`Q?%^on|NdScFKZZ+MD} zPX_$Dq(%7jku>-aBB9)Kp*;;UAJRgLr5ghI3b9X78JT-8UoM{VK@W zJxIkAA|e_%c^|NPyuMfEYH{&NY=7+cfN%PTIBzIEk`}(!h`U6CY&vy3Xsvl zgwnmX;ufT{41845Faq@gAGJNvm>dsDy0C|FddDHG18hWsiQ7N&k&{>5_-Fo4%&dM+ z45zNJh=PH(LQ+yGpqI(i7D`deX*XH`Es{!z8krMmL6>2&07p3}a#*`bBVG|k$t*aK z!mSNt_}P`0MAiyIOS^FH;aF1zlLj#ANX;Y3Ci$TYW>+>5%1|UK$OjSAw5AX(b#M+Q^{gMavY>Ad0RWg|Pia znx35+FFmq~nMa0L*)PWF6Ui6{c06(T(AFnD_Qa9fZd)!y_0o_f^?L$qgBxzRVdl{V zd2`WVRw=6TE-jBeOUrGF^g9nC)Tje|N1^ZONChX`)){eb!sG6fK?}KbMZ2V@l$B^$ zcO;_^RautfQ&>HzWYGTWL8VT5LLjS|`EV9mz za+7gyh0=?GlttEgxSH(3`qfcT3uHNM#Uw@6B+w;SiqyGQO3P|Uh#I*BC5Tjl5=AX1 zojBq6S88OBMlf{BSm$ePZV9 z$@`Zu^Z3>GeCjJtf8xJ9wyLy@iHf7@?|kFYd3iH(8Y5JBmRZ$k7H8_F>RerujqI=z zxu$cYx>y8V=zOE_bwEBa)sl4&bRex@+7@;=p_KKw>kn7c@#*`zeJeVy@!6+y^K}0A z?B~la!tjbW;_S{_fZ5BVb@NiiIBz+g`2_Emm!H)$Ph-cyUjSb5GdM3e z_T{{>Alp0&5_#v*01}pKXWS20t-DLx;%l#H-S@RqP8}EeKef0=6!R}LSTzN46v zIsPox2{tUjEb!pZ{?y%j|H%vfY*j(}kO4JLt3`nY7T9?ujKu!zv|-*YFpbJmK#rEG4ZSpvO}<{xlD06lR{QvdAXQ`G#iX zLFJ#JU={(>Ke9>iNadiM$t9E$jy`MBqa#D(CM32ov~9wZuRz!0=)?h62OJsZ5^maE zPuW4HfbhL^S)3DiCdozzu`+%jm%C%`?7}1Cx$TFpe0cwf$3C*MFjfm}v=#DcTzrT$ zc`1ff0m{@-Z|OLzR*$C{tohENM%`2>eNQVB+B*_Ba=v>odN_I6LDtm=CTy3ueREYT z8Agegb9HcW$?B}*rPEIWr+*8{k>7zB%wTTUOCfi^7P#`wSlan=WXUulE)kr1IA@V3 zZ8xXf%|HGb?0wN!aCFD(u%^gAK5^_GPrM?SriNR?-?CIW*BywZk!MJ1L#Ky8NHqIo zWd|!Qm?-A1SF6XJ%}tgub#c!hr|6Me>lZKhSO4w*n!oa8zo5B5qmR&?6Pa5nooi#+ zH1iJ=m{re0&%?BJXeKC_(pp>coKj--X_b3D+%4?k*D`p$AgI~z(9*|vfh37n&p0@ZLhi}{sQ%owUf@`<3LY>HgC%v+Hr}cpoCJu zJ5DQ^n?@m&fpAVs#}R~5EKQRvJ(;EA`1IMud&hHI@7r?r*gmn`!zXsx}H)DDBdGOB-kJ#uC2Y(rI-%q!GgzdcI z7Myv*uV5@@ux6Nl1i1Zsa+bB&v#dJxF(`{h(;SrPqDS8Yz1p4P#GY#P_z<(RMO!(* zYTiDsEU&0d)>XeD<>%$XzPDqYU_)ClH6HuPzwwJV{LI6%HPafQ%j+?Y|`-hU&#_l zvV_SUdbV`a1QgLrqoW?yRwp!Nb*#p+YCn|YW)f)f!1A=h3iGURorA>E5+oiO24|O! zoKh-=Ay?357#tvG9ftqt9Lq!ThGX~*Q9v9MBU439;OK= zwN+D-Dmu5*hBZIYijNXWRgMKIYl@)MeTMF6onQAlSZdW=O4=tnTkV*RUH>>ljwgl2 zhqy_@JL|n5NxFz$*?3ts5tK|kb-L@Yg6g5fG;`y0^`HrE_`4xzKSNWVRa||HjK|Aj zy!vQ9r1;2GwzNN$Q%}vFJ$4{@?)1ZZ4*%w%VsQ-(wWxkK;W;c2 zTW^Hgb^}w~oyNPZQxM=~yAV**@rXcr;3sQsacFtYy)9fQz4V^S_gG}W%8@vV_cmUc z2l78Le{bF){x?j`JukOb--5vvufyt&TYw$cAr+BuZdjZ>265tRq@Pmm?)*iRyPD-6 z96y8UJ+Hy)a0kvEc^t=!#YL;I$(t==2VqEE$EX_UQa60O)*w z>k&|_j9fSKFAHoMf?431|L2E(b;r;A-qCc&o}bTO#&wd+(W^+Fy9E#kK{Q9|s6wFT zVXCczK&*`Qc0yXVDouJrp?Vk{wRKVOX{IZ|Z4qf4rI$Nu<_boj(jleOvyp9gq!YH@ zW=DsGr3=y~rADhEdbJz?CmpU1@(vtAY7s>p#u}~$d)7vD%c( zDyM=ibBha)VaMaYjnxd`Cjicr==(`1e& zC5!alnv1DV2UnGg5K=*|4ahxRag92b&V8g}Uoge2{-^SFt!T^~M~lo^KV&;3N*aCP zsJ|)r(urO=1X73Bm84E*Q?Hv@Oy&jMnXnBx*`Z;wJw%!<4aUm{q)Z;k?Qn;(Rq@mo zapvIQu_K2UKm4^rz(-R=aF|PWzwEI@4E9v}x~c8DiZYt%3G8J4WxtBy?`(Xeu}#0* ziS_NMx^y^w($FO@`sP{Rbaa(xb%=8A=FIG6$o9Me!`-)Fb@ywKZhby7v8ikyn-6#Y zYv9q3zm7Cf5c2tZKaO<2+Cx95w-3qW;unfo z=2pvMj{3~(3i*72> zTGk~>90{$pI+4n@?R|8}%1=0Y%E2Tx{i%mhAAb|k5!<(Kzx?d*c@HBQ?kM+lGZq3_4wXwX zOx~ZofbT@Q5~He+Ru^sZeaYCQVT>Q?{9MA>MnFS((Kj7!VcOzqxaA#bZr$9n^=hnM z{eM92emSz8HzS>1i(%D>HN$E?#&Y`)0;e88W9}FCj*0taH-0bXU-pwYC*1e5z#|`q zwMa8qU(ka)9yiWUql+>e|cR4jRg<>&ef#sEDbr3~84^w92AHb=D{}by7 zld+r)f}KD8d)E(V@%u|#_S`HfF)Cj)C4Bn5s~M4wb&_676G&Mo_2%uAIO<8c+FdqD zX0@lLTdLvQ8w%DuhOqo0do(&ktnQR;5-3$TP+igr7QVePnoY{sE+`cU|@LfoC84$WP6q zcM}oe!`$5E&s&|j@(7Y-m=txUoRv}?^;+)nhN_Iot~uVflj%gl2+8C+kx2+xUxYe9 zPOh!fKiBxz;(fHpRn6`chO>Jy*nJb^Ro{+u=Qm@#?S-iKHIBF_IQ9*QFa1DXN1Ykr zv>Wr(m+9%Pn0f23U~${aFcFHz;0r$pocwAXXP1u|c>E?MrXfPzwanA-o^YCA7IQCW zW@a!wGhH4+v9i2e?zSPNG3Knubomx6K70`C2%DN<7I@*?-#)wWzQ6r1R<>R7qcS&> z=yzED3irLz?9fE9CX;Yipo?0r4olo=I9&3l6xs&hLwf1w+B=majgTe z&e>K!hVV5=nl%1RvS!OQ!b;hU&!gYc>x$^OL^CK!w7;Xb;_$l{r?-mn_;@D7@xf^2 zh|C5L&(1%6*V*CL2d=#9f877D1H}AS~0o*OK^2)D}%rIIJTjbw{W>!^&Og zYln>1Yj_mN)O%W*#??e<6}WOscauJ6n;@MuNmpiT|LVF5?~qJXE5yyVO->kC?k-W3 zB)=s1eJ*J@3a3Zo{G}u6lFWvTM5BWuC~`YlIs06GbvQY5=I(4b_4TP!^GC34$B}El z@=M1Kee#oybF`mD#D#Cu%Fe`{OP~XxY1F?a zPT`N=Mc>6sIwCF%S7)SOg}06gjj&(Rq>yoOCd;ZA>uO9EY z_Fpe=zv2grds+wdJ@gTbdR``A$YZ$(p>$T~CJS1S95QO$;WT=p?ht*suiI_uIy(2( zk96Er2Q9(66HgcmsBpt_;hfrFWCWTk+8r72D(p0Q!f~BtmW>jb9!tjKX9ugNzd9Oj ze`L5azi;~Z(&0TH`&WmK967QHclFsknAvgddsYWKK3N@srd#+(2}-S&jPmbNL#y0CmuVj^QT(317}p8_r?N+-_u7z6(=Vyb@=3y$++{ zHbks3mgj-bzAqoZkbkd4 zIrnSSE|psosl6}D`Ior`vzT+ava*s7kB_QFkct<`adsM6i}1 z1yvP1xU05p(pbe&4}A-w(bC0SR`;ITB%N!Pd`eGcB&4-SQ$7|jwX}HuczW)h;qv04 z)!~jKbH^S%yfoPIb+U}5S&Sf zUsw6gC-Ts;3%-M;;i(Qfck+Bck1yP$9dB1MdMGRUo)mt)IiH)83EcOkj_ z7A$SQ5fN*ECqD;#?e8MEz^22LjwBgk%PW2yr?2~7bjBzjYx>;#^C73lCi{5eV9B+l zd#%cNNI&W}p#1PoDuP)o?kPxSafEI`Fw=4m%uIcQ%Tq{3&&P>Fr?Ad&DeeW4J^K@X z?Kignn~&T*JG=0+%iFJdujqL@*Orcpr1Dd3tYr8*77 zY=CZfprLytUBQjll#SS2NMD;=KzBXb8Pa5cRx5eQjzp^D=4HDuB z*XJ3n_fwUdvb9UcSY3Ly{1Z>#j%2t6v)iu2VAoApx#Cs~ciw>IxoZ*8AL8g8C9$a; zz`Vm2l7?dNX^iCI|AD!y-if7|E6@qY?#nHxPpddwovI*k<(O*^z{v&D?Z#>1C3<}I zx-0p#8ax=1X@Ovku*C`<+GZb5uJEZ6bf71ri$Fa7IS{HDL(E?l$+U;F2f zPy9AIgR5I@AD*Fd3$)Z3YLw|ot(lccN&o>5k0QffXbm~thYUveq6)su)j1z0jYEWg@Y|D)2#_RMIK zOxE2*%!KWrb2L6Rl%-Qc`Hmoi0UW@dL{_6`393p-yG z4szlE@TI>}ogO5de%SZn)~USG{?Ze^FS?M_7X5U4qGD^JndzBod!iMxJyA7{D9tU( zFTuirN3aeN38oEk*-!q$pF4Z?b^j(CPJgpI2eUwEZH|%Qh^Y2vzHGeZOgdIc>r#5d zG-_6ZR0=fC+7<|qR#*bXoJf(4PG)j&Vvv)_T-77n7M{E#U7C9E+OPbK zE8KawTMY*j1l7P!;)MCW2XTPq^khj6)mz+^F?r>nJGlj~63>CqOHb1zGRDKI-bXSOFQ zPwz=Hx)Aaka(>?}Sf_{tlffJQ;v44nf6HI}&a*qN`HAuLmYb_Ku>)ZY}D*@?8T*s;fZ^Z ze(48u3*vJ7M}?cGfS+V33*yxDPE5V%dmyiQH?l2PV}xl8PCbnDiBABJ|2DGGB08b# z$4%F=+NQtD$1E2HfjXQ!C*=zA1jAzg%elFdaIUVbmPbTpQXdal>=lfEhEx0g71k*( zLMyeQAh!II55E$-w*UEbZuSRPr?y<%$T6!T3D%jh0hU+we9Qp3bmI!jGuBCj!W1jC zWp0feAIrw_xxsk(&it!s|J3T~L*vKi4_|ZOcONeI5sipA57>*n+m7wL{IC?F+?$q8 zdp6%mz6QNB@ngt})`N~ZEPd#2rReI`CC*TX-WCq%);V_d?-MSRMvA`qxK?N(#6?>@ z$Vt%jju#`_`xfAeH(|WvB^W0&*!0L!h_C#8$Y(zjmg`Es0%6LGbqgLl#Y8x7a5CmE6`TX!ztz<+2>qrL>($ zFD=q^JUDxLpPZSwM=Y-%9#2glntSf?!`Qv&sc-p%4<5bq&O4WJ{+jQI2o6JB_DzrE zDlkdiRLZ&x9vCQzjMa)!ZrRHZC^4*&LOKotEGx+oGyuMb-x(n5t+z`1}m#iBy#ld z%;Colo;vmQNAS^)rih4GKM=`|mpqUq!*BMIB_EOMLq;Z*T?^9Wi>Gh6wN4ArkHD@4 zdF><9mDq>Uc`hF(J&24*hUHdB)4Ohh*!@b3_Phz$`BIE>w~Y>w4^xXfegN6ZamLdj zWanDOx%>0+;o`e*vtV-R>eJSA)JKnpoSU7)U^p_=Je+++lE~*}VmQs_aIXrZN}Vj`YRWV(VT<{Y z;)&tv^5JYa^?0&$`k`^M<F@RuOzmbY z_iNChx#+x!I{L-ewc`TX$&f{^8SBV}sO@YToxIa>fd3<*vlR&ah(H$|VDz=6qetGB z8@&&ZR(XMX+a%*SaA7Dda=_rPG|1*rAb4Fk%tp{D*`|4RM`JgUO z+jFkZ=Ezm&w^R#!^yxhXip|wWqt)v49z8rR)1Sn`fq#v4j7Tug1Fn6;8|GHt_8s3e zn!EhwQ`@h&X*yfpHA?38WK&a@<>YXBI9}PAWa;kFU~adZ8qAenEn~TyjF(U3m&elK z^gLG5`I&6-xz*v82I?TYV=Km&yw7iNcOQX_OK|PGx6kfO!A&f?w?>d zw-?Ed8!)%`)i|^J_4)PnSm}90;)RA-T?Fp_0OT{DLV0Z5xmYHLPVuQ%k7F#;^kys`IDmDGNH8xxrf|az2@V}9 z4ylQxG2)WK%$DolyD~NXiSnjP$4}+D$Z}!3bT)kn()sFuLe{`e=|a2J^jviI8WL1_ z)aKrXu9n|6g5B4`G|4tg4dZTtxvf_t-SY-aUG)YmZ-04i-Mj+hb+i?dSjoxdJ&Ih) zmMx3R=L=Z(lz0C`Oc-twz1%bSWY;oY#=SawygD9oCbwQr4W}>~k4g(>mg@a43+rWe z01I35!gJRM>ll$>MnpthH0+++{rnTtS3cJ8IG4^zhwn=+Ld1k4LtVE>>SHN!@4X!& zx|73DTz%1&p0(E7^*#CC9d{3O&+m@Jpf!Dre_^E(gBi^1yb7%1h$@!%#fg|gF zkLnG!tSurUVzVLtD*xlWaeb?FJC^d7bmFwJZZzCX=fE}YT{;o&z715bFP!xFyY9jx z8|vgZlIDx2OB@J<=Lm7gFXYZyheGLYyLaR1LM~-9Iqig2lf)k6vQ3_(p|D(yR~E`Y zEF8#(O+SpOEmuM8xEWJdz8=}mn=#&T1JX%1dM_-N$L~UN9;4d?a=G zsOoC@4VB5zXn@bHEq%W9a%l?fBEgj>3O5}-f*c~M#dT5zOhh#Yvp|-=Cv$R-md)gs zHUhaU5D8{PM8rkKl*qoiS_}(X@y6Q%KGxEEiIuuZVSWR=XD{IDOOHD z3FLq2GoQh5IEU#SFM-(o3XFEY8iQ>wL^`_{qhfWsJEUG5`J3i^Wc4JHGf!Y}^bTal z??!rRe{LZ=Q~I-{ivF_ifU(3%4?*>C&RPwl%jjg}+sYsZuD*Az8(r#)tDDn7;~=u7 z^-}#;%*`zbW-%O|rG#8c^B7;m20OJPa#`8m|MhFFiuxsNG1Com=BCT<(iZ4lwUo;y=(V9cg}L`1|z#i5lU#(z|t@vK)-ChEF6n3oCS zvs_s+#IgYJ9fnV*>o0-eUVmWH6auxlv{`rDIDOVF8iq@sPp=OG{_wpNbqwytC!Akb zox4p`Dn|w;MTqFq&aKUIV>&Borw@)F{p}N{9yaas zygq{Dll74>icp6gvIK`d21HAEIN>SrlIZuGzPxwIkqgOOvvR^8&ZL34XY~tSM%No3 zTrw=sd>^iUIPr7kL2^1!*JU?fI32$F%n^954z$7dq3h}faSz ztV;rDSdJ_|G}C9@GtVmnem+^BAI&dEpYYx|5H0sQE}9p{UGVxs`Qjt5oGh334Fcv6 zFP|y zU}5@(f>E_*^@$Mh6-}&5oXXe~%sORt3stkRm&v8VeO*L7n41clyqK@~;n#b_WK{uM@Z|B=X@vgak zvk~c)7x95`tYAICKvFO|8gnX`#woC&%N&E02B~!$@cvx`#IxUre=F_L63RM0kjjm~ z`DGANfz+A&)R_N{JqCyYl-J#oVOFUXsr5Xbh(Q+crSCkI%drWP<0R8P5^eoa z0Dq><3#yL)x3?z0rafJt(az1-o$pRlpB~|8xnARV6}~S?#1&g^4?bwCc~LHtO$Qbm zCnr63S9l?};74&kPkTgJGOtWb=lVf6R-Zq`qaN2`!R$ zy_f)g1`yr!{5TKl!2^&E+pM@m(-Btn2kuPw?h>9q#U53?W#?wag0a;zbI%j-Jzfld z9xl&CM@u{Pgovn!@_pZVY7ZaZ19Z-#(cTZf;;zC2ub=Kkp{RXs1L`PwLTBlOm%Uey zJ&~$w^7I9|CfGSBwmLc^wu?cy%_c2r;c}HdurMo@qr1GUot120zNa<~`lx z=^t`~FQ3o^zak-tEdWu(Bb$D+IG$Qzyq-QK&h||gOXtWbl!c!%1Q;1{C^M;*PtcUb zWiSdJb7**W!K`HRt^%-TQ*41BB@gXxCn~Dyo`2+sEsuO(&WX+GCdI>1S+0qhxBWRa zgq4hT%jtk7+JOqQ_V5ZAUD5U~CyQ0B(pafoJryNn!3VHFG^JGIWAtROD$c_0{E;Kq zZ(pkp;G(>fU23wnR?h_JaBNS>v<*jHYkUQXDTSTxVSJ~fSafEhfHFV(Jo$TZhPsdQsFlFqna)7Kc?YGJ1)vVVN$!I*dy;dUokR$Uh` zmDjER(c`G;R_~RFMYy*=RaRn-NeTyFkE!UDw1BU;94@EZJOG+}H0P&Vc}g}fpzqv%$=8Cd z{dFB~*s>SmQ#)@h;0D*D`)Pimgxhih{-{-${byHNpmAAj#ud7sawucH09O^k*_ggM zJT?Kb)Q^ppP|T7i!`tR4&ALD9x5lOxadSO3q^#8IrKci3H2|!}5-P(#(v9}1^^P=p zAJVWH5z zWKIr~8U8y1H8QtNT-tl5k>!(%@8Sw=ZYx$1!lPl`zT#d6r!Z%yk?+ZFq&Y5pB6?eb zixsBF(NiO)v+t?s{gKLEw@pUNi4S8qHY_#10(0lmq`xmAaCTrDJJ-wF*cZ_VgK2V7nG!xA&g;wbh-KmhoQU1tG8^O?xSUVCZYd zQJ%O^F?XeI zsZm}4>$;>J$5~(CIgrgMw>FnSnRs#2IP~tOQw|phLY&8sf5#ue;~|aM+pJ?ecLgJs zm-fIvWa}5d;)~>hyTCL-Via4)&Wmh1>(EaqN!%G_sqr!ETVEyce#73TuCaVMH5_O% z&I=0CyOil0GyCny4TVm~Ac~m7OA(Mk%00+bL5>)0Eox$a!k;1^d#cxGypU&~tdbQ# zNEw*ei(k$+#W3fT<-_cp>UFuSRJJ$0ITfJ}X0bT%O$ZWfRYbA9d1>D~?TlmyaAoh5 zPH1`4zXdD{9*ZUH+?d9r6ChMiME8%C<08nh&=~N_h%PNBZhLj zgiWfT|LM2hM8^%|X;FpU9#{*luhp|tYGW~>28)xdrhJM1glKh}0VlkI4ZjN~zuc-9 z3bhM29-(Y%m2c$aV_N?6#VW2(@?4h7T8{n^lNu67?{*l>x})w*mbQEBMnvl<7VI4F*y}TYZl<2XKr*ama#bJ6-V~@`pG8>|um{`dG#0Jw zvYAZ{qJ#h2?N)Oc>(vnE8?;Holo*iHciy|VnpNG7yccXc3H#inPALi`ki_ggj_U16bbo0c#()n3dN8N*#nA8dHcwh zH%n1(5nT{@*_>LGV=Bq;ukR`_w;73j+A6n?oypw4kO)n;I?U-y{v2V-y&sz=cz&#r zR({Djgw;`=D0;8sX!<9vJG*Ue`?sezw3xh7VBEnP`f$7|4rth)^kWh{QUduOQIw*A@=#kcol$NgIvq$x_o>9N336MYYsgMkDjhkdwEndd3C7McEeOx(saxI1ZM;%!#T`4dpU!$!XwxN*G;&MZ$gl2|1kSbKD zTxT}t10dnz>mS6n*g0DJXCTnR`@S#U(r>f(YyoWXT^or|u9Y<6m0N{;Lq5MZ0y8}B zZv2)&A3Ng~8cr9`h5(UHr+9{>CM)|0xn?*Ze0?Z{ha%{(tOXOIx+b4{&>6LEa_|XaD#*<3MyknjYTIIgPhvw1_q}!6_O&w*nA@^- zzKlvxskGoM>>+s3r{X`<->|brz5DLVTc?hR4iGeLK+Qaa4u3E*GSV~7DI^SMgWZ)+ z8(U${PXjr^D&JbtkbCl%gV`}^c6Zn^oh}ML%QAXt+$Dw{;3Q%Hb>S9Lc_cY1@s}uT z>t>{`A$evSKj1wRAeRLv>$t_D$tVlB`U|hI{^EPGA<47(5RI#WqJG02ma1&Q?Ke9o zM*g=($3Jv?{0>{-zBn*}NU!M+#oaQK&J4TgMl5CfQJ`ps9*S&h;fUgPay5QCY46BU>{ zCp)%#B`P+o-rmCluSA?X=?=qwS_9H2IthK=4I>qga`q1Ba*jfubQTC|%g$St1pGL0 zE6ZkobaXYrFe1cS?B+h8wY_Ly)e|*y!O>__f2@4`>uRB-j=;9ULK3)LUwWy6K$4jG zEsAUIf_!aH$;f|aAxHF&*>Ak62FC+kE+mH2)@5$WZ!uHp@vLcEKU;>=MQ_v{fqyz> zQBIe7rnSp^s*96AF#7ETICl~kJzQ-Invvcf+0dP6u+VCUE>OT{^yGqZ0ka8AiT{$wyOTn=%AjCk(g!f(YR4r8T9??~5S1FIu!YQLvspKjH z_#?ksF$3y8X6O{YO8)|~EYx34%w2lW-2E(5mg0PgWXXO9{F%32<``=m?a2c0UaKM6 zvLZuX!$48Pngu3z$PCjX7=?T4eGdb}5cLQc9bRkD!sIjON8PV>**y0kM7j5qs62=hPR}p`tHk;bcmY%y|NYr~X0|Lr4;yIH zsoqJ7SKaMV>Wi52D+VAMy=U`t{{t7;B@^Cl3DEGN7Y~=1T;drZ|6}uVh5hrpN0Osx z!wFK0ttpx$jES|08G4O|fM#gEu_hipC=WdgjdO~Dp7}q>O@(SNw z(#=Y#$9enGDr18(*+Io zMArVNlIE|A?}^OWX5qWWGru}d;7%>WfLp(dHWM!4kdf6slmN*w*+#$5Qkj*i{1jNQ zG!KqkwR(6>ZTuMSEdM=LP^}oHbmD~Ps}NqGQGn2e(VVRhshf`&Zxdv{a%XcK-+)jW zp?IGl-Jmsj3uh}6Te7^uV{%VkRhpsy6Az@!ceg!**@Bn)3i>oy&Lzf?0?k(Q8K z?N7ht-s;o3Vx8}o=(ES8MRUq(Wo2DyXo5j?8&fEgimHiOlFm=+3o9`DpW&(FLG~rT zUE|ZR&&z5y>9fed{WEgn$j=$pD^hyiLwkBdPTV?^0eF#8!XPK_RRfMi=p0krBKI0y zqf`D9;BHDm9Psz30b+=AXbC^C5Y|;^rYGDSt%QkeEd($V$|YVowZsF+FjOJ`gt11DZ-Jpoi_5vPUFlh^m;gm^Vk&!9?Xp4@j*~8( z1VMM>MZePU5JOdxYdv82zjm2XV*bQq#V=@wWHhTGC0Wax(m2TEEPOA{F$i zXwXeGvr?1zG0Js6(@}9$g%85b+$nIED@crKS8=r;c^HUD99q2<*gFWlz@yg7Mlb=x z6icfRTMKjOmU;<;94Qhft*+kNkL5HaLkWUTVRng>ffiN{G%Pf=@tvbl%H+~;J{yMh zf!A{6rOiknJ|i+4}BGlm;KF{ zkdfL9FFZJMi``^#m+7V`@$fGF1QZ~o>@-@FHLCw(9`m*47k-0xP-_HTasH;fResf% zgGrSZ%yiGss>|gUF+A=`{7B#;-F+`XEX#z~MF>UW5WredUPa-uMnrqfTUmdq*(ydt zjUrV)V%oeLcH! zhOvvV0(tJmsMi+s%`d12+_^igr#D_}cli50{z|=;JL=pCb&@LT_$vOQLVuGZtRatm zGe8g7y6Ck~t7Fvy`lz!Is}lPAV#og^g@~$^ha$&60&zk;)WBY#+2|0Lf2AW_>= zD_xY2Rmr+KS>9@haK9V+tk3Y+kA5;a*UiMZsrUyv z0d*)4<1JbBz9R12dT?k9YyP{=CVKg17)TiV2aC3WZZM|>FS*{7G`!Uf6Ib?pjqWIb z%nmh}Xq$g@HBQGdAk&5q98 zuC5xjb~5f}HA(zz`rQwQhIA7Gv;;n>+VVy=?v2+cSo7k5@f;Y3NvqxilFYjQfcYh%g49 z1n5n<`cwFh{T}tayp}~ab0>siaeiHrX`wb=J+`rV&*MkdAP2;s&+$k>j#}FyZxF+c(@S zPM}hb8tDMi46HwCOPCNda6A#G%^eaG07S^OCdY@<&xdTsO7$7cHReO@8SM?}oW|G$ zl#AGz1(dft_ao5E6@o}wIAPI9C6 z8ztV3brAed)7tXBkk=bb#Cpu($o(f{0pj%xXx+`Fxiq*rG9YK}KP^nWampy02_J37qZCq|D!wr~A9RF|v>g^l8|MU0H!6GoG=(8K z$i~~0pvHyU(G8RK5OtWOp@BR+Z$A7MY;WJ>K^7+`j~JYygFd|9STpHhl&byT^R45% zzOmb`2RAO`Yj?>aaFQ&Bu%)enef|?spj5w-u$I=c0kb>l-+{evJN0dQWN;R~zPQJ)#Kf*A#yyw-iu<^ycIRgmq@>qZwSUzpyp}kL zYrFZhczQkgv{;4fc#v5ZwhzctJ1m{Yv*pt{Kc!71bA zTV5YNLaPlS+%0N)5&LUoUtzHgfzQD&{H4!I6TlBw^R8RekP-A|ub=?A0LDzZm5#P~ z(v|mAKQ>WIi!hB928NCB;KmZ1By?wcuh4k`yS8sQetAyD#a_!qlj-r3j_m3GWET%b ztnWU`FMjT{A;Bf!be&bZr?a*}+fi!&N(EUuo*qk6BW!U(v?atQb{cmA$I8GO`~7CY zV)l{X<{l=GFg!WG4bVpuQ`lTcCCFDNBP|h4^dg96($MaAUg&d#1$3wrI=~%zkau#>2U3y1f#sN~&*gqC)%fnv)cOeZ{A>>_Y75oc+j+4ycmJ^+s^27^;*e8~c9qv%V`nmm9l`W!= zKv_k_%*TfmASTkrZ6G78n!D$FU-L?CC))M=o7PNdB+>tF-b$o!8_JuHBCta%TEjc% z_`;iV3x-F&hswB^g`ly6v#Q$GLQwpK@|VRV)k&7*saOfmUJS9T{6Cx#NWPr|0JmS!M!71$8AX)ITyv8}e?Wz=EWDFi$XtRULm+x_UE#f~? zVtUY6_g|_PInXMaD^FjjX@4kCg<8x4W6@THP3j$F8 zW(p!#PwT^^s1`*%Z#@;7ZdzV}ikw)+zuMZzS?!0h< z8ZFQOc3^H5KF;@btprq!EvNDRdM38a!&)JKf&LL0+)dEz0zxRg$dIU zJcMV9>4A2qMO3|vvPLqL$an2r*YlsVIxx`jJv^nx1dulCLoXn-0Lj3!NzaPVtaS)Qiu$lo%{_Gb4m%KQeic-Se`Ewp;Ei(#d}_GB{ZV;VL$oh2)y>_mBl z_0$PR*_$W9Hi%?;QzzMw9^2Q`9&1 zvE7O?V$xa{Fl3EAy7CX-=~f9pAN(}2&sPL~RknfW?kZZ$##K2#)lJ`QZ(ZhnlAaA! z-%UW4%%FCyXbUYCehL&CekhlD{|%u}eoL@y`$6Rc-|*u9GMNg->(-kusWFHwaWLpl>W3esK zZ5*y$2)3W;svN+qwN%?h$F?#P2czBTJ7-9&i5`$Kvk4vh>dV&8gmxnl|53h=YR=;# z=gB7DO7rl4(pIR$g7bUhOWWvn^J$QsP6I*{`D3qioSbOWMmbYG?0B{AHW5BE)hR;@L>MJ%d zA-!ohA`F_REvLV`;_*`RRg*!}oUl(27wWZPpJ3kPSLN4Ndx#KzjTP`g!cy$6PkhnR zFZ|W*`S&8VG`FxKn3@j^%7g;i@Qhn=RCNg<6!t8xp!E2!!uR{aj(Nx#%9`5;Hl=+J z%i|FJAvp#9*NmmY$Ww}kCsYaBOlKeAaP}rn=)h5;cS)7heu~X=I|5bpsraOV-X)kp zQT~z~X(SW>__;K#3MjD4zu3BcIK~1Z!ie~ZLK&Fo871(rB3RA;bjh9C>h8O;|32KnN zsuf4y_d-bc&OFoK4^c_Y`5R_Scc(88RCHze8mC508V0R57b;hd_@+M^xp@gM@Fe+K z;I%QBy#7_}hnMzoAH}-nR{c>SG zGAAxl<%>K1D#eH5*JqttvQ1)7iLvz!SCw>FK>(~cH8qt~qQNm+BkXvasUxrRVq{sA zfg|WQ^24j%^g1J~&+!{GlTOyuK1oQp;X6V@vFZF|QBlqiqsKF_?E|>;4Zsa+;-CkM9z@sf$ zBC=!rElWGT!-9>Fq9G7QDEm*KIO=<@e%*DbNGlT+WlmZ)OVsA>?gs-2>^c<OD1K%@0gnlm$YldSOA|zL`pzgPUqv92Ll10t z*>>-L+vwpjB%TvsdfbwC(c~yd#fE$jTlrdRO5|%oGzHf_3}VUMn=GsTdbl^U{`($^ zRJvR(vioTaGlMX?Bxx>ukS1&&Del^_4zxATb$ky|wX<|A0+0oTF3#2LN=voA?!z+& zI1%QMG>kXB5^X()LE`yO8MuLqk_R*}h^J=rg~H=A2f8_j_&8v>|AD8;U1Gs&!t9Lc zfv~5ySF(4*@gk|1y9pmmiJ069?ZiZk^*L)k4!WiMK#q(t4(k6g6aJ_E2#@$h^E+&? z@yYJO)GurnG#8GFj3`por{$A7=iXbPFVJzucooZYit>k)R%#%m%%HUR8iXepU~D+Q z!pkn|AZgTiT8Ed0EAjZcu+TwdD+3aSPB^*MjGS!30dlbN{Q2tfB}Q|@0ynhnrczx7 zSd!@b0hSuZQ1gfiI;)VbsolGXf>pqv2Sx*OX&R^6Fv zDdmVe9NS#!MyqeajU2XH#7Su z8UL3ta=W)~rE0OjesRhlQHeMUu}Xh;l&f7lXai*@g%N20eAU&1vcY?$CmDzq2;zjTkj%iiSH%jiz?~s za2`P~15<61O^NBQ*!&MJWTrhZ<0{)M#ZP1B2HsMgjvYpB-^oPN9GhGGujKrvZ(2(6 z#eeChn{_MLgD$Nv8XZFa8Rq!X21%|L6X zFGzq8(+Dz3oMO!Tu=K0@I4x?s3oun{o^=$Yj6j-4hQ86b0VA!5;f7?xEIF14^Lai| z;`GlE3sQ$=dy+g=XDRx@{ckFC zT2%g?QTVcj=kWAH1*Gzo@7u6WS^(!M3()a}2m0td!v3L%tZKll2^(A&j?k!5El&Bo zv@Iz+*H=6;haMFrKw#p)Ju5ptJb5h?<(PWpk06~`q%oQng8jFUd(_l2)!kSNOj*Y- z@=-`f*D0#e4iHxry>w^{{kt1Qa>({^x9?=!@r$osdnxf{a+I%l`1+)M=U~O zq)(!Y!Vl1#)u|}CA7kw!(^CH|{t3D^E9i@iGXdnOxWAtYA{*Dg-W_)gm$mZ{^f#Xb z{8G_m)N7U=Xmc`Ps-uzPf&0W3ODSt44j<2v$hqhXMCH?DTvJ)ivW=*Y)XF;F7lncg zJxuU>X$rszM_Z)go==x4dYmzT@KtiGt1)#$b%ig0tE-(Vitlw2g5BKL32yzJTFdWi z$z%Y=y*qK1Cph;^M&^HGZ$gg>qHCYE3aRH}(swh`u(8<5I#en-WyBNiswvhVuZ%Lp z8pLQsV*=X!q(>$aU21<9cbm$9mvztr5$d9s=TLQ1TQ5}Gfew`bMs-t2CI z58b0kcIHabY=rMXEI=FW)9uwh>gvWA$5`jbmr%4Bd0OEH{hGZkb3dU zW4yaCvDw67H6o>vDL$vWf^%oRb97o1!wvI!hT#sVyri<7(?}027?91L75XalNiJJG zJ#x?m0V8X9>g=(=N_Vc-|9@VZ$tWDoVYpCzp#t04Y$ZYakp`xjeyLU@fcFR|BL{uz z2e+26bPbVJUkN7kNdiq4x>MLXBwDOHG;v3GeNW6nFJXd#!s(Z%j0-n8HH0P$80Bm- z%W+}kb*F`^s7-Is!R}H^-^mg0G!`}`dNM@;l(|;1wwN*L2jBc}289vv#UXBwl8Rweo zr4O128bm`x_J_|eS`Y*|>voEz%!=9V=Lty9`J0_FR2wmN@|W#_^y4-$3uZ5y#|dz5 zu{q5Cezv-ZYf2@kK@rPk2-de(C|~Ki5qi}N`n9C1nzzE~*Ex_Tx|vWiDrdI)MDld- zba^R5_R$<(!rqrI;sZZ@?q+8ek4n@AOi4LOe#zs`QYCFRFVVkouZHz8%*f> z^M^`o7E+7gXY1M;&MgLq+rQP7sJ4P(6%(clfp^+%Gl!@jU+~_|g3qyki806d42vY;KCr!)y*)?v3 zFFZXvwU}V}OyhN{mEPXo_Fsp%e;ue>CZsO{VUr`s2ZrPBG$SmpN48WO{)_cQtR`at zw4p;+X)5D0wcuy-A9k<3El(GQR%vT=3wg>A&H4x1sAmG>m5G-0*eVW}GC}9Giv4h@D%UFoxnCyMoJ8YYCA;IX z6Rp;(==e|twoC^nt9?=z6Yo@Y@GR?zQEqwC#(l~#+AagkGRi7!AgJxJLww-mbL>=^$?1;gF>zWYFyv`X3hAY?p zikaD6oI)mSzn6Gue?RJo8tF7&IaedRaG%0U;4+f1zApsuNdvHHD}IA{L>92-vwh~% z_%D;n6)Y>uEw#m!e;T_1rKUMg+vypYjc}}F@C!XLQdor*r7_wi@d~>n;`wrpMix;l$Y?xuYVGyba%K^-HY*46_%ohJ40k(~A7i-ed%yI}~7K$*^Br|2APEQyQF6s1UVipnp4MUJX$?emOoZ zW1q$^j+hgj{Y{O$Z2qecN`kNt;dS-?VZQCElTrW2X zj~DT~{N#ZxsJ6~wmQO&UFLFoom!EU@C+I}@F$*0yzU$JHrfBfZQ?GL^sfVaIVmQ*p zY$@{ZT)qY?sxqdOfcFV?SqXr@=TkTKx| z;Nd<07dLjk`rl-yW-FYxh)W&w(^xt$62??Oc9r53RCv2r!W}_yMzb@#;i6|_3t+7( zb#S7<4(_|uuen_0Rh#H#BWkGYR&YKPXW)2c*2KWkfPHB_^*Dlo9Kb_ZIc{`gQ*4=j z_g1+5@B*)c_75zI9Qp{V9_5KfxD0Te5QB=27^BuV>NxRg%S~>%yziu5CY1nRidGwk`=*G(g+3b~;>cO5`Pt{u9U-I3R z)Hl-bIR`Y-zts+^?{k|oMbdwGEIhmy-9N4L+Nt67t#0%Q7h9nx^X|nIDgOx? zOZCyW@{)DzL57s_5!-GuBxX!T7%GC3{gT$K^k-zDE^YK=8qwMH-pQGUdZ*Mqo8)e- zcMu!FmL+F-{jw{k9|Pj>9`T&4g$wY>JRx4i-&Li}iyCjbT9{?88iICYxF;MhVfB+a zn4FOrbgvDh8!|Zb*g3q8wiRBPO^gykuMI{WMyAybSw{wXwy?X5em)VHpc7t*3Wh0b@u5$ zoV$KZR3#Bj%ID)UzJtkk6oOXIPkPczK4l!HB4%bC@)GYMf;~fE{Lb6t0XD z{Ka#;Rg zWs)5F-FR``+-GLCsD4;4tPj1W!SwGuVV#e(HGPd|Iz-`tGQ$-ewu>AJ{y)H?-bAD% z;72C$ydRJPv}#bP{SLi8se}jB##9ZfdwFgQ4iO3_TCE*+^xp+WM*exY{a+i*oTO>* z*|eI3-;E$i065_0%dN{BR%YfQH%1};MvIxIS?bKt3B?Yq@9yfMJZt3{jCP_GkZfKs zV}@(QH>E@?88!u|zpeuBZQm+|b&^Qnrqt|s8rbZr4^LY8|JQGrs{3HExglrZU8^v> z8%#seB4>VNZrDixIU(E+ICDyLoH{rP=exHiqrYHQDs9aWo|Cue+bzA*5YG`q>h`p< zp4EJ!qu?WFoTbk^@1$@MwmSc=P5*;{piBeBSihOKhz zvg7I%EDV9395Mt)29e^FPiYIon}wyMG0Ty~nMGkUbn5b9)haj>tX5MJgQp<@`$msc zP>Df}7YISbMP?db<=hm$J^xXYh;!e%;Qa!rmHzKcaA0>Q>lwo~E|2S{t<1d~R6+NW zs)FrlsRiOrMDn}T9r$Xp5nLaWHSEI}(kF3i0G<_hY$rvI+huxQdpEl|!u#nYN{zB| zO%&RZM(@&m0fl_NY;ale(69)xh{oQH^#4EaXOCXjSR9^NRIlkqt-NvXJTpLEfa_6P zEzg(ePw4ipvamE9V>9zRsM+0VyEI>CjCY(1SjjJC@qC$n9OB@FaRaRu&NASLDGqFG73$+?0nKR+^iFR-!_`z_tV6N8lZu#fxYE>7d7FBoafD;dbP@QUTjhrLU-BLgj||7$9)8l! zN8#+9qwMOS%5Rd^>{Q`DMxA)>D)dH{vep?SwU~z)a|EDjC6eppnv@<1fB6`mFsq%m zxweu+$++`WwihP=xxEzs+|bc663)@=xMg0yH)3tRd3SYrxCbhBus7l5Xm#hQFdQD1 zXSP)^<_p=_&UF}D47}MQ2y>g4#andktyUwwd#8LMCxCR z&cH-5H1Ru`p!VL<$3nisx8O&8Is@Rfp74_tA8|E;9a}*~Q!>$231&`H+5nsiLm$$z zNc+_^oSLe)mVs=kDGwa0;XA}n{@+&P$o=`82496ie+R~HLy-MtDs{L3Z=pH~cK<@p z)QZdDkuXh&tF8-K@UHYv1A3r)331HVXm2d40q7W~>B^`XvSaw)VQ|}diwt&S>^rWT zXF?>t4M@<-K%qJH6Ut66)Z^Fm*UO35 z(ncQt|4(+3j`Qy(vo|c~%Rq>YH=6V=5ieV?JgOl?(kg;LfoTxS421lomI3yBVh2M^ zR!XQ^GkbvZa44el0e5GY$@Th3tXpM#`o&*-6dB1(T~u#$!M-!N;9wOF-ojd8q=r?W zzhlzr%wn|b9#C15a_6$+a`yD8eke33vGCA&svV$Uxf%!Mz4J1vt!euUr2lstp68_c z*>asF**9Ix4SPZhV=4CV1x*Q*Sfx+Nhp3(~XMnEuXO#zvLkG_{x-M}n?cN>ov)%UZ zAV$O@BA*BSivqMw)LU3pl;*v+o{xhJkpz!W*HIYCY|6q?qkt4tfOvLXm2F#f2gLAT zBN6%27VVe1^Xt27E?}DzV^;@{4W&@Jl4ax!zTd37UdgKaeS(7? z;r<|Hl7#y?^!gP@Y + { const { - theme: { colors, variants, moreActionsButton, defaults }, + theme: { colors, moreActionsButton, defaults, variants }, } = useTheme(); const [isDrawerVisible, setIsDrawerVisible] = useState(false); - const [feedbackModalVisible, setFeedbackModalVisible] = useState(false); - const call = useCall(); - - const handleRating = async (rating: number) => { - await call - ?.submitFeedback(Math.min(Math.max(1, rating), 5), { - reason: '', - }) - .catch((err) => console.warn(`Failed to submit call feedback`, err)); - - setFeedbackModalVisible(false); - }; const options: DrawerOption[] = [ { id: '1', + label: 'Noise Cancellation On', + icon: ( + + + + ), + onPress: () => {}, + }, + { + id: '2', + label: 'Start Closed Captions', + icon: ( + + + + ), + onPress: () => {}, + }, + { + id: '3', label: 'Stats', icon: ( @@ -61,7 +75,7 @@ export const MoreActionsButton = ({ onPress: () => {}, }, { - id: '2', + id: '4', label: 'Feedback', icon: ( @@ -71,10 +85,7 @@ export const MoreActionsButton = ({ /> ), - onPress: () => { - setIsDrawerVisible(false); - setFeedbackModalVisible(true); - }, + onPress: () => {}, }, ]; @@ -98,11 +109,6 @@ export const MoreActionsButton = ({ onClose={() => setIsDrawerVisible(false)} options={options} /> - setFeedbackModalVisible(false)} - onRating={handleRating} - /> void; - onRating: (rating: number) => void; -} - -const FeedbackModal: React.FC = ({ - visible, - onClose, - onRating, -}) => { - const styles = useStyles(); - const { - theme: { colors, variants }, - } = useTheme(); - const [selectedRating, setSelectedRating] = useState(null); - - const handleRatingPress = (rating: number) => { - setSelectedRating(rating); - onRating(rating); - }; - - return ( - - - - - - - - - - - - - - - We Value Your Feedback! - - Tell us about your video call experience. - - - - {[1, 2, 3, 4, 5].map((rating) => ( - handleRatingPress(rating)} - style={[styles.ratingButton]} - > - - = rating - ? colors.iconAlertSuccess - : colors.typeSecondary - } - size={68} - /> - - - ))} - - - - Very Bad - - - Very Good - - - - - - ); -}; - -const useStyles = () => { - const { - theme: { colors, variants }, - } = useTheme(); - return useMemo( - () => - StyleSheet.create({ - overlay: { - flex: 1, - justifyContent: 'center', - alignItems: 'center', - }, - modal: { - width: '90%', - backgroundColor: colors.sheetSecondary, - borderRadius: variants.borderRadiusSizes.lg, - alignItems: 'center', - paddingHorizontal: variants.spacingSizes.md, - paddingVertical: variants.spacingSizes.md, - maxWidth: FEEDBACK_MODAL_MAX_WIDTH, - }, - top: { - flex: 1, - marginBottom: variants.spacingSizes.lg, - flexDirection: 'row', - }, - closeButton: { - backgroundColor: colors.buttonSecondaryDefault, - borderRadius: variants.borderRadiusSizes.xl, - width: variants.roundButtonSizes.md, - height: variants.roundButtonSizes.md, - }, - topRight: { - flex: 1, - flexDirection: 'row', - justifyContent: 'flex-end', - }, - logo: { - width: 190, - height: 134, - marginBottom: variants.spacingSizes.md, - alignSelf: 'center', - }, - textContainer: { - maxWidth: 230, - textAlign: 'center', - }, - title: { - fontSize: 28, - marginBottom: variants.spacingSizes.sm, - textAlign: 'center', - color: 'white', - fontWeight: '600', - }, - subtitle: { - fontSize: 13, - textAlign: 'center', - color: colors.typeSecondary, - marginBottom: variants.spacingSizes.xl, - fontWeight: '600', - }, - ratingContainer: { - flexDirection: 'row', - justifyContent: 'center', - marginTop: variants.spacingSizes.md, - }, - ratingButton: { - paddingVertical: variants.spacingSizes.md, - }, - bottom: { - display: 'flex', - flexDirection: 'row', - marginTop: variants.spacingSizes.xl, - }, - left: { - flex: 1, - flexDirection: 'row', - alignItems: 'flex-start', - }, - right: { - flex: 1, - flexDirection: 'row', - justifyContent: 'flex-end', - }, - text: { - color: colors.typeSecondary, - fontSize: 13, - fontWeight: '500', - }, - }), - [variants, colors], - ); -}; - -export default FeedbackModal; diff --git a/sample-apps/react-native/dogfood/src/constants/index.ts b/sample-apps/react-native/dogfood/src/constants/index.ts index acdf552504..27355178fd 100644 --- a/sample-apps/react-native/dogfood/src/constants/index.ts +++ b/sample-apps/react-native/dogfood/src/constants/index.ts @@ -2,7 +2,6 @@ export const BUTTON_HEIGHT = 50; export const INPUT_HEIGHT = 50; export const AVATAR_SIZE = 50; export const BOTTOM_CONTROLS_HEIGHT = 76; -export const FEEDBACK_MODAL_MAX_WIDTH = 385; export const Z_INDEX = { IN_BACK: 0, From 442850eaafbf737d99c37786f5114abaea16728e Mon Sep 17 00:00:00 2001 From: Kristian Date: Mon, 4 Nov 2024 14:14:22 +0100 Subject: [PATCH 20/35] feat(design-v2): screen share flow (#1552) Implements design-v2 changes to the share screen flow. ios ios ios --- .../CallControls/ScreenShareToggleButton.tsx | 27 ++++++++++++++----- .../LivestreamScreenShareToggleButton.tsx | 11 +++++--- .../components/utility/ScreenShareOverlay.tsx | 5 +++- .../src/icons/ScreenShare.tsx | 12 ++++++--- .../src/icons/StopScreenShare.tsx | 5 ++-- .../CallControlls/BottomControls.tsx | 4 +-- 6 files changed, 45 insertions(+), 19 deletions(-) diff --git a/packages/react-native-sdk/src/components/Call/CallControls/ScreenShareToggleButton.tsx b/packages/react-native-sdk/src/components/Call/CallControls/ScreenShareToggleButton.tsx index ed9480fa35..6a9256e0d5 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/ScreenShareToggleButton.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/ScreenShareToggleButton.tsx @@ -6,6 +6,7 @@ import { StopScreenShare } from '../../../icons/StopScreenShare'; import { CallControlsButton } from './CallControlsButton'; import { useTheme } from '../../../contexts/ThemeContext'; import { useScreenShareButton } from '../../../hooks/useScreenShareButton'; +import { IconWrapper } from '../../../icons'; /** * The props for the Screen Share button in the Call Controls. @@ -32,7 +33,7 @@ export const ScreenShareToggleButton = ({ onScreenShareStoppedHandler, }: ScreenShareToggleButtonProps) => { const { - theme: { colors, screenShareToggleButton }, + theme: { colors, screenShareToggleButton, variants }, } = useTheme(); const screenCapturePickerViewiOSRef = useRef(null); @@ -48,17 +49,29 @@ export const ScreenShareToggleButton = ({ return ( - {hasPublishedScreenShare ? ( - - ) : ( - - )} + + {hasPublishedScreenShare ? ( + + ) : ( + + )} + {Platform.OS === 'ios' && ( )} diff --git a/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamScreenShareToggleButton.tsx b/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamScreenShareToggleButton.tsx index 18b2b82422..79207df6d5 100644 --- a/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamScreenShareToggleButton.tsx +++ b/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamScreenShareToggleButton.tsx @@ -33,8 +33,8 @@ export const LivestreamScreenShareToggleButton = () => { styles.container, { backgroundColor: hasPublishedScreenShare - ? colors.error - : colors.background2, + ? colors.iconAlertWarning + : colors.buttonSecondaryDefault, height: buttonSizes.xs, width: buttonSizes.xs, }, @@ -52,9 +52,12 @@ export const LivestreamScreenShareToggleButton = () => { ]} > {hasPublishedScreenShare ? ( - + ) : ( - + )} {Platform.OS === 'ios' && ( diff --git a/packages/react-native-sdk/src/components/utility/ScreenShareOverlay.tsx b/packages/react-native-sdk/src/components/utility/ScreenShareOverlay.tsx index 27b9aa2e28..27b5d0a815 100644 --- a/packages/react-native-sdk/src/components/utility/ScreenShareOverlay.tsx +++ b/packages/react-native-sdk/src/components/utility/ScreenShareOverlay.tsx @@ -67,7 +67,10 @@ export const ScreenShareOverlay = ({}: ScreenShareOverlayProps) => { screenshareOverlay.buttonIcon, ]} > - + { +export const ScreenShare = ({ color, size }: Props) => { return ( - + ); diff --git a/packages/react-native-sdk/src/icons/StopScreenShare.tsx b/packages/react-native-sdk/src/icons/StopScreenShare.tsx index e636b9852f..d9b68c2ffe 100644 --- a/packages/react-native-sdk/src/icons/StopScreenShare.tsx +++ b/packages/react-native-sdk/src/icons/StopScreenShare.tsx @@ -4,11 +4,12 @@ import { ColorValue } from 'react-native/types'; type Props = { color: ColorValue; + size: number; }; -export const StopScreenShare = ({ color }: Props) => { +export const StopScreenShare = ({ color, size }: Props) => { return ( - + - + Date: Mon, 4 Nov 2024 18:12:06 +0100 Subject: [PATCH 21/35] feat(design-v2): add feedback flow in react native dogfood (#1551) Implements the feedback flow in the react native dogfood app. --- .../05-ui-cookbook/19-call-quality-rating.mdx | 120 +++++++++++ .../19-call-quality-rating/feedback.png | Bin 0 -> 192242 bytes .../react-native/dogfood/src/assets/Close.tsx | 19 ++ .../react-native/dogfood/src/assets/Star.tsx | 19 ++ .../dogfood/src/assets/feedbackLogo.png | Bin 0 -> 130347 bytes .../CallControlls/MoreActionsButton.tsx | 56 +++-- .../dogfood/src/components/FeedbackModal.tsx | 197 ++++++++++++++++++ .../dogfood/src/constants/index.ts | 1 + 8 files changed, 381 insertions(+), 31 deletions(-) create mode 100644 packages/react-native-sdk/docusaurus/docs/reactnative/05-ui-cookbook/19-call-quality-rating.mdx create mode 100644 packages/react-native-sdk/docusaurus/docs/reactnative/assets/05-ui-cookbook/19-call-quality-rating/feedback.png create mode 100644 sample-apps/react-native/dogfood/src/assets/Close.tsx create mode 100644 sample-apps/react-native/dogfood/src/assets/Star.tsx create mode 100644 sample-apps/react-native/dogfood/src/assets/feedbackLogo.png create mode 100644 sample-apps/react-native/dogfood/src/components/FeedbackModal.tsx diff --git a/packages/react-native-sdk/docusaurus/docs/reactnative/05-ui-cookbook/19-call-quality-rating.mdx b/packages/react-native-sdk/docusaurus/docs/reactnative/05-ui-cookbook/19-call-quality-rating.mdx new file mode 100644 index 0000000000..ea569029fd --- /dev/null +++ b/packages/react-native-sdk/docusaurus/docs/reactnative/05-ui-cookbook/19-call-quality-rating.mdx @@ -0,0 +1,120 @@ +--- +id: call-quality-rating +title: Call Quality Rating +--- + +## Introduction + +In this guide, we are going to show how one can build a call quality rating form on top of our React Native Video SDK. +It is a good practice to ask your end users about their overall experience after the end of the call or, while being in a call. + +Here is a preview of the component we are going to build: +![Preview of the UI](../assets/05-ui-cookbook/19-call-quality-rating/feedback.png) + +## Submit Feedback API + +Our React Native Video SDK provides an API for collecting this feedback which later can be seen in the call stats section of our dashboard. + +```ts +await call.submitFeedback( + rating, // a rating grade from 1 - 5, + { + reason: '', // optional reason message + custom: { + // ... any extra properties that you wish to collect + }, + } +); +``` + +## Implementation + +```tsx +import React, { useState } from 'react'; +import { + View, + Text, + TouchableOpacity, + StyleSheet, + Modal, + Image, +} from 'react-native'; +import { useCall } from '@stream-io/video-react-native-sdk'; +import Star from '../assets/Star'; +import Close from '../assets/Close'; + +const FeedbackModal: = () => { + const call = useCall(); + const [selectedRating, setSelectedRating] = useState(null); + + const handleRatingPress = (rating: number) => { + setSelectedRating(rating); + await call + ?.submitFeedback(Math.min(Math.max(1, rating), 5), { + reason: '', + }) + .catch((err) => console.warn('Failed to submit call feedback', err)); + }; + + return ( + + + + + + + + + + + + + + + We Value Your Feedback! + + Tell us about your video call experience. + + + + {[1, 2, 3, 4, 5].map((rating) => ( + handleRatingPress(rating)} + style={[styles.ratingButton]} + > + = rating + ? colors.iconAlertSuccess + : colors.typeSecondary + } + /> + + ))} + + + + Very Bad + + + Very Good + + + + + + ); +}; +``` + +:::note +For simplicity, the StyleSheet is not included in this guide. +::: diff --git a/packages/react-native-sdk/docusaurus/docs/reactnative/assets/05-ui-cookbook/19-call-quality-rating/feedback.png b/packages/react-native-sdk/docusaurus/docs/reactnative/assets/05-ui-cookbook/19-call-quality-rating/feedback.png new file mode 100644 index 0000000000000000000000000000000000000000..26abb8bbe6e1964aa9198281446594cac319bbb7 GIT binary patch literal 192242 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 ( + + + +); + +export default Close; diff --git a/sample-apps/react-native/dogfood/src/assets/Star.tsx b/sample-apps/react-native/dogfood/src/assets/Star.tsx new file mode 100644 index 0000000000..1ebde674e8 --- /dev/null +++ b/sample-apps/react-native/dogfood/src/assets/Star.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { Svg, Path } from 'react-native-svg'; +import { ColorValue } from 'react-native/types'; + +type Props = { + color: ColorValue; + size: number; +}; + +const Star = ({ color, size }: Props) => ( + + + +); + +export default Star; diff --git a/sample-apps/react-native/dogfood/src/assets/feedbackLogo.png b/sample-apps/react-native/dogfood/src/assets/feedbackLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..477432050bfd8a1cb0ba9e3c9a64f73dbc200814 GIT binary patch literal 130347 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

fB!tLyMGCPeH5VI&_@wfRR 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 { const { - theme: { colors, moreActionsButton, defaults, variants }, + theme: { colors, variants, moreActionsButton, defaults }, } = useTheme(); const [isDrawerVisible, setIsDrawerVisible] = useState(false); + const [feedbackModalVisible, setFeedbackModalVisible] = useState(false); + const call = useCall(); + + const handleRating = async (rating: number) => { + await call + ?.submitFeedback(Math.min(Math.max(1, rating), 5), { + reason: '', + }) + .catch((err) => console.warn('Failed to submit call feedback', err)); + + setFeedbackModalVisible(false); + }; const options: DrawerOption[] = [ { id: '1', - label: 'Noise Cancellation On', - icon: ( - - - - ), - onPress: () => {}, - }, - { - id: '2', - label: 'Start Closed Captions', - icon: ( - - - - ), - onPress: () => {}, - }, - { - id: '3', label: 'Stats', icon: ( @@ -75,7 +61,7 @@ export const MoreActionsButton = ({ onPress: () => {}, }, { - id: '4', + id: '2', label: 'Feedback', icon: ( @@ -85,7 +71,10 @@ export const MoreActionsButton = ({ /> ), - onPress: () => {}, + onPress: () => { + setIsDrawerVisible(false); + setFeedbackModalVisible(true); + }, }, ]; @@ -109,6 +98,11 @@ export const MoreActionsButton = ({ onClose={() => setIsDrawerVisible(false)} options={options} /> + setFeedbackModalVisible(false)} + onRating={handleRating} + /> void; + onRating: (rating: number) => void; +} + +const FeedbackModal: React.FC = ({ + visible, + onClose, + onRating, +}) => { + const styles = useStyles(); + const { + theme: { colors, variants }, + } = useTheme(); + const [selectedRating, setSelectedRating] = useState(null); + + const handleRatingPress = (rating: number) => { + setSelectedRating(rating); + onRating(rating); + }; + + return ( + + + + + + + + + + + + + + + We Value Your Feedback! + + Tell us about your video call experience. + + + + {[1, 2, 3, 4, 5].map((rating) => ( + handleRatingPress(rating)} + style={[styles.ratingButton]} + > + + = rating + ? colors.iconAlertSuccess + : colors.typeSecondary + } + size={68} + /> + + + ))} + + + + Very Bad + + + Very Good + + + + + + ); +}; + +const useStyles = () => { + const { + theme: { colors, variants }, + } = useTheme(); + return useMemo( + () => + StyleSheet.create({ + overlay: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + }, + modal: { + width: '90%', + backgroundColor: colors.sheetSecondary, + borderRadius: variants.borderRadiusSizes.lg, + alignItems: 'center', + paddingHorizontal: variants.spacingSizes.md, + paddingVertical: variants.spacingSizes.md, + maxWidth: FEEDBACK_MODAL_MAX_WIDTH, + }, + top: { + flex: 1, + marginBottom: variants.spacingSizes.lg, + flexDirection: 'row', + }, + closeButton: { + backgroundColor: colors.buttonSecondaryDefault, + borderRadius: variants.borderRadiusSizes.xl, + width: variants.roundButtonSizes.md, + height: variants.roundButtonSizes.md, + }, + topRight: { + flex: 1, + flexDirection: 'row', + justifyContent: 'flex-end', + }, + logo: { + width: 190, + height: 134, + marginBottom: variants.spacingSizes.md, + alignSelf: 'center', + }, + textContainer: { + maxWidth: 230, + textAlign: 'center', + }, + title: { + fontSize: 28, + marginBottom: variants.spacingSizes.sm, + textAlign: 'center', + color: 'white', + fontWeight: '600', + }, + subtitle: { + fontSize: 13, + textAlign: 'center', + color: colors.typeSecondary, + marginBottom: variants.spacingSizes.xl, + fontWeight: '600', + }, + ratingContainer: { + flexDirection: 'row', + justifyContent: 'center', + marginTop: variants.spacingSizes.md, + }, + ratingButton: { + paddingVertical: variants.spacingSizes.md, + }, + bottom: { + display: 'flex', + flexDirection: 'row', + marginTop: variants.spacingSizes.xl, + }, + left: { + flex: 1, + flexDirection: 'row', + alignItems: 'flex-start', + }, + right: { + flex: 1, + flexDirection: 'row', + justifyContent: 'flex-end', + }, + text: { + color: colors.typeSecondary, + fontSize: 13, + fontWeight: '500', + }, + }), + [variants, colors], + ); +}; + +export default FeedbackModal; diff --git a/sample-apps/react-native/dogfood/src/constants/index.ts b/sample-apps/react-native/dogfood/src/constants/index.ts index 27355178fd..acdf552504 100644 --- a/sample-apps/react-native/dogfood/src/constants/index.ts +++ b/sample-apps/react-native/dogfood/src/constants/index.ts @@ -2,6 +2,7 @@ export const BUTTON_HEIGHT = 50; export const INPUT_HEIGHT = 50; export const AVATAR_SIZE = 50; export const BOTTOM_CONTROLS_HEIGHT = 76; +export const FEEDBACK_MODAL_MAX_WIDTH = 385; export const Z_INDEX = { IN_BACK: 0, From 4f39ec519f2deca33b326fe2249c21987ddc1f9b Mon Sep 17 00:00:00 2001 From: Kristian Date: Wed, 6 Nov 2024 12:42:25 +0100 Subject: [PATCH 22/35] fix: bump webrtc version (#1558) Bumps the webrtc version to `125.0.0-alpha.3` --- .../react-native/dogfood/ios/Podfile.lock | 8 ++++---- sample-apps/react-native/dogfood/package.json | 2 +- yarn.lock | 16 ++++++++-------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/sample-apps/react-native/dogfood/ios/Podfile.lock b/sample-apps/react-native/dogfood/ios/Podfile.lock index d5f434427c..10d948bd49 100644 --- a/sample-apps/react-native/dogfood/ios/Podfile.lock +++ b/sample-apps/react-native/dogfood/ios/Podfile.lock @@ -1145,10 +1145,10 @@ PODS: - RCT-Folly (= 2022.05.16.00) - React-Core - stream-react-native-webrtc - - stream-react-native-webrtc (125.0.0-alpha.1): + - stream-react-native-webrtc (125.0.0-alpha.3): - React-Core - WebRTC-SDK (~> 125.6422.05) - - stream-video-react-native (1.2.10): + - stream-video-react-native (1.2.12): - glog - RCT-Folly (= 2022.05.16.00) - React-Core @@ -1478,8 +1478,8 @@ SPEC CHECKSUMS: RNVoipPushNotification: 543e18f83089134a35e7f1d2eba4c8b1f7776b08 SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17 stream-io-video-filters-react-native: 8c345e6adf5164646696d45f9962c4199b2fe3b9 - stream-react-native-webrtc: e3a201b101ee5dc194daf8915aeacc54f0ba53c5 - stream-video-react-native: fc9c932706eba2416db5416335f69bd33d64d7ab + stream-react-native-webrtc: 05ef9fc88a273bebeaa3b651d232eec290a39f5c + stream-video-react-native: f6aa195dbaf9f72945ad2d16d709dc1e40ceee2b TOCropViewController: 80b8985ad794298fb69d3341de183f33d1853654 WebRTC-SDK: 1990a1a595bd0b59c17485ce13ff17f575732c12 Yoga: 1b901a6d6eeba4e8a2e8f308f708691cdb5db312 diff --git a/sample-apps/react-native/dogfood/package.json b/sample-apps/react-native/dogfood/package.json index 5493988a06..2ffd0a8b85 100644 --- a/sample-apps/react-native/dogfood/package.json +++ b/sample-apps/react-native/dogfood/package.json @@ -30,7 +30,7 @@ "@react-navigation/native": "^6.1.10", "@react-navigation/native-stack": "^6.9.18", "@stream-io/flat-list-mvcp": "^0.10.3", - "@stream-io/react-native-webrtc": "125.0.0-alpha.1", + "@stream-io/react-native-webrtc": "125.0.0-alpha.3", "@stream-io/video-filters-react-native": "workspace:^", "@stream-io/video-react-native-sdk": "workspace:^", "react": "18.2.0", diff --git a/yarn.lock b/yarn.lock index 0642bcd8e8..40f2abb866 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7760,16 +7760,16 @@ __metadata: languageName: node linkType: hard -"@stream-io/react-native-webrtc@npm:125.0.0-alpha.1": - version: 125.0.0-alpha.1 - resolution: "@stream-io/react-native-webrtc@npm:125.0.0-alpha.1" +"@stream-io/react-native-webrtc@npm:125.0.0-alpha.3": + version: 125.0.0-alpha.3 + resolution: "@stream-io/react-native-webrtc@npm:125.0.0-alpha.3" dependencies: base64-js: 1.5.1 debug: 4.3.4 event-target-shim: 6.0.2 peerDependencies: react-native: ">=0.60.0" - checksum: 582eb9b32548484af02821d2d46d96885066c296324d0ac29b019a674a77e5a941c1ec6cdc8b19f7ae4da80e75ee7c9d8a9efb0dfaaab9533abc524dc4db383d + checksum: 4204e5534e8af9065af28164e64f7db43272c24da85945078472a490e1b39cde5d559ed6e312bad8ca5933c5506c43066243e8380aee19a34711ef81bed12d21 languageName: node linkType: hard @@ -7989,7 +7989,7 @@ __metadata: "@rnx-kit/metro-config": ^1.3.3 "@rnx-kit/metro-resolver-symlinks": ^0.1.22 "@stream-io/flat-list-mvcp": ^0.10.3 - "@stream-io/react-native-webrtc": 125.0.0-alpha.1 + "@stream-io/react-native-webrtc": 125.0.0-alpha.3 "@stream-io/video-filters-react-native": "workspace:^" "@stream-io/video-react-native-sdk": "workspace:^" "@types/eslint": ^8.56.10 @@ -26187,17 +26187,17 @@ __metadata: "typescript@patch:typescript@4.9.5#~builtin": version: 4.9.5 - resolution: "typescript@patch:typescript@npm%3A4.9.5#~builtin::version=4.9.5&hash=23ec76" + resolution: "typescript@patch:typescript@npm%3A4.9.5#~builtin::version=4.9.5&hash=289587" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: ab417a2f398380c90a6cf5a5f74badd17866adf57f1165617d6a551f059c3ba0a3e4da0d147b3ac5681db9ac76a303c5876394b13b3de75fdd5b1eaa06181c9d + checksum: 1f8f3b6aaea19f0f67cba79057674ba580438a7db55057eb89cc06950483c5d632115c14077f6663ea76fd09fce3c190e6414bb98582ec80aa5a4eaf345d5b68 languageName: node linkType: hard "typescript@patch:typescript@^4.6.4 || ^5.0.0#~builtin, typescript@patch:typescript@^5.5.2#~builtin": version: 5.5.2 - resolution: "typescript@patch:typescript@npm%3A5.5.2#~builtin::version=5.5.2&hash=85af82" + resolution: "typescript@patch:typescript@npm%3A5.5.2#~builtin::version=5.5.2&hash=29ae49" bin: tsc: bin/tsc tsserver: bin/tsserver From f420d911949947aba5838cc346fe615ceaf17a59 Mon Sep 17 00:00:00 2001 From: Kristian Martinoski Date: Wed, 6 Nov 2024 12:51:42 +0100 Subject: [PATCH 23/35] fix: yarn lock issue --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 40f2abb866..6fe7d85206 100644 --- a/yarn.lock +++ b/yarn.lock @@ -26187,17 +26187,17 @@ __metadata: "typescript@patch:typescript@4.9.5#~builtin": version: 4.9.5 - resolution: "typescript@patch:typescript@npm%3A4.9.5#~builtin::version=4.9.5&hash=289587" + resolution: "typescript@patch:typescript@npm%3A4.9.5#~builtin::version=4.9.5&hash=23ec76" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 1f8f3b6aaea19f0f67cba79057674ba580438a7db55057eb89cc06950483c5d632115c14077f6663ea76fd09fce3c190e6414bb98582ec80aa5a4eaf345d5b68 + checksum: ab417a2f398380c90a6cf5a5f74badd17866adf57f1165617d6a551f059c3ba0a3e4da0d147b3ac5681db9ac76a303c5876394b13b3de75fdd5b1eaa06181c9d languageName: node linkType: hard "typescript@patch:typescript@^4.6.4 || ^5.0.0#~builtin, typescript@patch:typescript@^5.5.2#~builtin": version: 5.5.2 - resolution: "typescript@patch:typescript@npm%3A5.5.2#~builtin::version=5.5.2&hash=29ae49" + resolution: "typescript@patch:typescript@npm%3A5.5.2#~builtin::version=5.5.2&hash=85af82" bin: tsc: bin/tsc tsserver: bin/tsserver From 187f2e4182294c5fc163e7fb11c577a5d93882bf Mon Sep 17 00:00:00 2001 From: Kristian Date: Tue, 12 Nov 2024 15:03:23 +0100 Subject: [PATCH 24/35] fix(design-v2): color consolidation and other fixes (#1556) ## Overview - consolidates the theme colors - adds support for Light/Dark theme for the dogfood app - updates the Lobby screen per design-v2 - updates iOS config so that iPad is target device as well - solves issues when the app is shown on iPad is not constrained in smaller screen size - fixes speech indicator issue to be animating only when the user is speaking - fixes participant name, network indicator and reaction position issues - updates the `FLOATING_VIDEO_VIEW_STYLE` width and height to bigger values according to new design-v2 - removes hardcoded Lobby video height const from the SDK `LOBBY_VIDEO_VIEW_HEIGHT` - fixes call recording modal and bottom drawer orientation issues ## Screenshots ios ios ios ios --- .../Call/CallControls/AcceptCallButton.tsx | 4 +- .../Call/CallControls/CallControls.tsx | 2 +- .../Call/CallControls/CallControlsButton.tsx | 9 -- .../Call/CallControls/HangupCallButton.tsx | 7 +- .../Call/CallControls/LobbyControls.tsx | 24 ++-- .../Call/CallControls/ReactionsButton.tsx | 6 +- .../Call/CallControls/RejectCallButton.tsx | 2 +- .../CallControls/ToggleCameraFaceButton.tsx | 10 +- .../CallControls/ToggleVideoPreviewButton.tsx | 10 +- .../ToggleVideoPublishingButton.tsx | 9 +- .../CallControls/internal/ReactionsPicker.tsx | 6 +- .../CallLayout/CallParticipantsSpotlight.tsx | 1 - .../components/Call/Lobby/JoinCallButton.tsx | 36 +++--- .../src/components/Call/Lobby/Lobby.tsx | 108 +++++----------- .../src/components/Call/Lobby/LobbyFooter.tsx | 95 +++++++------- .../Call/RingingCallContent/IncomingCall.tsx | 6 +- .../Call/RingingCallContent/OutgoingCall.tsx | 6 +- .../RingingCallContent/TextBasedIndicator.tsx | 10 +- .../Call/RingingCallContent/UserInfo.tsx | 2 +- .../HostLivestream/HostLivestream.tsx | 4 +- .../HostLivestreamControls.tsx | 2 +- .../HostStartStreamButton.tsx | 8 +- .../LivestreamAudioControlButton.tsx | 17 +-- .../LivestreamVideoControlButton.tsx | 17 +-- .../ViewerLeaveStreamButton.tsx | 6 +- .../ViewerLivestreamControls.tsx | 4 +- .../LivestreamLayout/LivestreamLayout.tsx | 2 +- .../LivestreamTopView/DurationBadge.tsx | 8 +- .../LivestreamTopView/FollowerCount.tsx | 8 +- .../HostLivestreamTopView.tsx | 2 +- .../LivestreamTopView/LiveIndicator.tsx | 4 +- .../ViewerLivestreamTopView.tsx | 2 +- .../FloatingParticipantView/index.tsx | 9 +- .../ParticipantView/ParticipantLabel.tsx | 6 +- .../ParticipantView/ParticipantReaction.tsx | 17 ++- .../ParticipantVideoFallback.tsx | 8 +- .../ParticipantView/ParticipantView.tsx | 8 +- .../src/components/utility/Avatar.tsx | 6 +- .../components/utility/ScreenShareOverlay.tsx | 8 +- .../react-native-sdk/src/constants/index.ts | 6 +- packages/react-native-sdk/src/icons/Lock.tsx | 19 +++ packages/react-native-sdk/src/icons/Mic.tsx | 2 +- .../react-native-sdk/src/icons/MicOff.tsx | 2 +- .../react-native-sdk/src/icons/Reaction.tsx | 2 +- packages/react-native-sdk/src/icons/Video.tsx | 2 +- .../react-native-sdk/src/icons/VideoSlash.tsx | 4 +- packages/react-native-sdk/src/theme/colors.ts | 79 ++---------- .../react-native-sdk/src/theme/constants.ts | 46 ------- packages/react-native-sdk/src/theme/theme.ts | 6 +- packages/react-native-sdk/src/theme/types.ts | 61 +-------- .../react-native-sdk/src/translations/en.json | 4 +- .../project.pbxproj | 4 + .../dogfood/src/assets/LightDark.tsx | 19 +++ .../src/components/BottomControlsDrawer.tsx | 8 +- .../dogfood/src/components/Button.tsx | 4 +- .../CallControlls/BottomControls.tsx | 5 +- .../CallControlls/CallRecordingModal.tsx | 3 +- .../CallControlls/LayoutSwitcherButton.tsx | 2 +- .../CallControlls/LayoutSwitcherModal.tsx | 13 +- .../CallControlls/MoreActionsButton.tsx | 35 ++++- .../components/CallControlls/TopControls.tsx | 10 +- .../dogfood/src/components/FeedbackModal.tsx | 2 +- .../src/components/LobbyViewComponent.tsx | 13 +- .../src/components/NavigationHeader.tsx | 85 ++++++------ .../src/components/ParticipantActions.tsx | 37 +++--- .../src/components/ParticipantsInfoList.tsx | 41 +++--- .../dogfood/src/components/TextInput.tsx | 50 +++++--- .../components/VideoEffectsButton/index.tsx | 121 ++++++++++-------- .../dogfood/src/components/VideoWrapper.tsx | 3 +- .../dogfood/src/contexts/AppContext.tsx | 13 +- .../src/screens/Meeting/ChatScreen.tsx | 8 +- .../src/screens/Meeting/GuestModeScreen.tsx | 54 ++++---- .../src/screens/Meeting/JoinMeetingScreen.tsx | 16 ++- sample-apps/react-native/dogfood/src/theme.ts | 31 ++++- 74 files changed, 644 insertions(+), 665 deletions(-) create mode 100644 packages/react-native-sdk/src/icons/Lock.tsx create mode 100644 sample-apps/react-native/dogfood/src/assets/LightDark.tsx diff --git a/packages/react-native-sdk/src/components/Call/CallControls/AcceptCallButton.tsx b/packages/react-native-sdk/src/components/Call/CallControls/AcceptCallButton.tsx index f9bf774c49..e08b4b7a7a 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/AcceptCallButton.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/AcceptCallButton.tsx @@ -57,11 +57,11 @@ export const AcceptCallButton = ({ return ( - + ); }; diff --git a/packages/react-native-sdk/src/components/Call/CallControls/CallControls.tsx b/packages/react-native-sdk/src/components/Call/CallControls/CallControls.tsx index 540ee1b718..6de5c02d64 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/CallControls.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/CallControls.tsx @@ -40,7 +40,7 @@ export const CallControls = ({ - + ); diff --git a/packages/react-native-sdk/src/components/Call/CallControls/LobbyControls.tsx b/packages/react-native-sdk/src/components/Call/CallControls/LobbyControls.tsx index 191b4d8205..078b1875e3 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/LobbyControls.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/LobbyControls.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useMemo } from 'react'; import { StyleSheet, View } from 'react-native'; import { ToggleAudioPreviewButton } from './ToggleAudioPreviewButton'; import { ToggleVideoPreviewButton } from './ToggleVideoPreviewButton'; @@ -11,6 +11,7 @@ export const LobbyControls = () => { const { theme: { lobbyControls }, } = useTheme(); + const styles = useStyles(); return ( @@ -19,10 +20,17 @@ export const LobbyControls = () => { ); }; -const styles = StyleSheet.create({ - container: { - paddingVertical: 12, - flexDirection: 'row', - justifyContent: 'space-evenly', - }, -}); +const useStyles = () => { + const { theme } = useTheme(); + return useMemo( + () => + StyleSheet.create({ + container: { + paddingTop: theme.variants.spacingSizes.xs, + flexDirection: 'row', + justifyContent: 'space-evenly', + }, + }), + [theme] + ); +}; diff --git a/packages/react-native-sdk/src/components/Call/CallControls/ReactionsButton.tsx b/packages/react-native-sdk/src/components/Call/CallControls/ReactionsButton.tsx index 34b8ef5b65..aa0522af8b 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/ReactionsButton.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/ReactionsButton.tsx @@ -3,7 +3,7 @@ import React, { useState } from 'react'; import { CallControlsButton } from './CallControlsButton'; import { OwnCapability } from '@stream-io/video-client'; import { ButtonTestIds } from '../../../constants/TestIds'; -import { Reaction } from '../../../icons'; +import { IconWrapper, Reaction } from '../../../icons'; import { ReactionsPicker } from './internal/ReactionsPicker'; import { LayoutChangeEvent, LayoutRectangle } from 'react-native'; import { useTheme } from '../../../contexts/ThemeContext'; @@ -71,7 +71,9 @@ export const ReactionsButton = ({ onPress={reactionsButtonHandler} onLayout={onReactionsButtonLayout} > - + + + {showReactionsPicker && ( diff --git a/packages/react-native-sdk/src/components/Call/CallControls/RejectCallButton.tsx b/packages/react-native-sdk/src/components/Call/CallControls/RejectCallButton.tsx index 8073c6a7f8..3ffb7f32ae 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/RejectCallButton.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/RejectCallButton.tsx @@ -63,7 +63,7 @@ export const RejectCallButton = ({ return ( void; + + /** + * Background color of the button. + */ + backgroundColor?: ColorValue; }; /** @@ -21,6 +27,7 @@ export type ToggleCameraFaceButtonProps = { */ export const ToggleCameraFaceButton = ({ onPressHandler, + backgroundColor, }: ToggleCameraFaceButtonProps) => { const { useCameraState, useCallSettings } = useCallStateHooks(); const { camera, optimisticIsMute, direction } = useCameraState(); @@ -46,8 +53,9 @@ export const ToggleCameraFaceButton = ({ return ( {!optimisticIsMute ? ( - diff --git a/packages/react-native-sdk/src/components/Call/CallControls/ToggleVideoPublishingButton.tsx b/packages/react-native-sdk/src/components/Call/CallControls/ToggleVideoPublishingButton.tsx index ecab938bbb..05a92e42c1 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/ToggleVideoPublishingButton.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/ToggleVideoPublishingButton.tsx @@ -27,7 +27,7 @@ export const ToggleVideoPublishingButton = ({ const callSettings = useCallSettings(); const isVideoEnabledInCall = callSettings?.video.enabled; const { - theme: { colors, defaults }, + theme: { colors, variants }, } = useTheme(); const onPress = async () => { if (onPressHandler) { @@ -53,11 +53,14 @@ export const ToggleVideoPublishingButton = ({ > {!optimisticIsMute ? ( - diff --git a/packages/react-native-sdk/src/components/Call/CallControls/internal/ReactionsPicker.tsx b/packages/react-native-sdk/src/components/Call/CallControls/internal/ReactionsPicker.tsx index c7d1b683f9..7d3a35e8ed 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/internal/ReactionsPicker.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/internal/ReactionsPicker.tsx @@ -104,7 +104,7 @@ export const ReactionsPicker = ({ styles.reactionsPopup, reactionsPopupStyle, { - backgroundColor: colors.base4, + backgroundColor: colors.sheetSecondary, }, reactionsPicker.reactionsPopup, ]} @@ -120,7 +120,7 @@ export const ReactionsPicker = ({ styles.reactionItem, reactionItemStyle, { - backgroundColor: colors.background3, + backgroundColor: colors.buttonSecondaryDefault, }, reactionsPicker.reactionItem, ]} @@ -158,7 +158,7 @@ export const ReactionsPicker = ({ style={[ reactionsButtonDimmerStyle, { - backgroundColor: colors.base4, + backgroundColor: colors.sheetSecondary, }, reactionsPicker.reactionsButtonDimmer, ]} diff --git a/packages/react-native-sdk/src/components/Call/CallLayout/CallParticipantsSpotlight.tsx b/packages/react-native-sdk/src/components/Call/CallLayout/CallParticipantsSpotlight.tsx index 439b45a11e..a588162dd8 100644 --- a/packages/react-native-sdk/src/components/Call/CallLayout/CallParticipantsSpotlight.tsx +++ b/packages/react-native-sdk/src/components/Call/CallLayout/CallParticipantsSpotlight.tsx @@ -165,7 +165,6 @@ const useStyles = () => { StyleSheet.create({ container: { flex: 1, - padding: theme.variants.spacingSizes.xs, backgroundColor: theme.colors.sheetPrimary, }, fullScreenSpotlightContainer: { diff --git a/packages/react-native-sdk/src/components/Call/Lobby/JoinCallButton.tsx b/packages/react-native-sdk/src/components/Call/Lobby/JoinCallButton.tsx index cf805c7fb1..c1559a8fa5 100644 --- a/packages/react-native-sdk/src/components/Call/Lobby/JoinCallButton.tsx +++ b/packages/react-native-sdk/src/components/Call/Lobby/JoinCallButton.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useMemo } from 'react'; import { LobbyProps } from './Lobby'; import { Pressable, StyleSheet, Text } from 'react-native'; import { useCall, useI18n } from '@stream-io/video-react-bindings'; @@ -22,6 +22,7 @@ export const JoinCallButton = ({ const { theme: { colors, typefaces, joinCallButton }, } = useTheme(); + const styles = useStyles(); const { t } = useI18n(); const call = useCall(); @@ -45,7 +46,7 @@ export const JoinCallButton = ({ { + const { theme } = useTheme(); + return useMemo( + () => + StyleSheet.create({ + container: { + borderRadius: theme.variants.borderRadiusSizes.lg, + marginTop: theme.variants.spacingSizes.md, + paddingVertical: theme.variants.spacingSizes.sm, + }, + label: { + textAlign: 'center', + }, + }), + [theme] + ); +}; diff --git a/packages/react-native-sdk/src/components/Call/Lobby/Lobby.tsx b/packages/react-native-sdk/src/components/Call/Lobby/Lobby.tsx index e4f59c65bf..d9fcb6086e 100644 --- a/packages/react-native-sdk/src/components/Call/Lobby/Lobby.tsx +++ b/packages/react-native-sdk/src/components/Call/Lobby/Lobby.tsx @@ -1,5 +1,5 @@ import React, { ComponentType, useMemo } from 'react'; -import { StyleSheet, Text, View, ViewStyle } from 'react-native'; +import { StyleSheet, Text, View } from 'react-native'; import { useCallStateHooks, useConnectedUser, @@ -7,7 +7,6 @@ import { } from '@stream-io/video-react-bindings'; import { Avatar } from '../../utility/Avatar'; import { StreamVideoParticipant } from '@stream-io/video-client'; -import { LOBBY_VIDEO_VIEW_HEIGHT } from '../../../constants'; import { RTCView } from '@stream-io/react-native-webrtc'; import { LobbyControls as DefaultLobbyControls } from '../CallControls/LobbyControls'; import { @@ -63,7 +62,7 @@ export const Lobby = ({ const { theme: { colors, lobby, typefaces }, } = useTheme(); - const styles = useStyles(); + const styles = useStyles(landscape); const connectedUser = useConnectedUser(); const { useCameraState, useCallSettings } = useCallStateHooks(); const callSettings = useCallSettings(); @@ -81,47 +80,25 @@ export const Lobby = ({ name: connectedUser?.name, } as StreamVideoParticipant; - const landscapeStyles: ViewStyle = { - flexDirection: landscape ? 'row' : 'column', - }; - return ( - + {connectedUser && ( - + <> - {t('Before Joining')} - - - {isVideoEnabledInCall - ? t('Setup your audio and video') - : t('Setup your audio')} + {t('Setup your test call')} {isVideoEnabledInCall && ( @@ -141,17 +118,15 @@ export const Lobby = ({ )} - + + )} + {LobbyControls && } + {LobbyFooter && ( + )} - - {LobbyControls && } - {LobbyFooter && ( - - )} - ); }; @@ -167,16 +142,14 @@ const ParticipantStatus = () => { { ); }; -const useStyles = () => { +const useStyles = (landscape = false) => { const { theme } = useTheme(); return useMemo( () => StyleSheet.create({ + heading: { + textAlign: 'center', + paddingBottom: theme.variants.spacingSizes.md, + }, container: { flex: 1, - justifyContent: 'space-evenly', - paddingRight: theme.variants.insets.right, - paddingLeft: theme.variants.insets.left, + justifyContent: 'center', + backgroundColor: theme.colors.sheetPrimary, + paddingRight: + theme.variants.insets.right + theme.variants.spacingSizes.sm, + paddingLeft: + theme.variants.insets.left + theme.variants.spacingSizes.sm, paddingTop: theme.variants.insets.top, paddingBottom: theme.variants.insets.bottom, }, - topContainer: { - flex: 2, - justifyContent: 'space-evenly', - paddingHorizontal: 12, - }, - heading: { - textAlign: 'center', - }, - subHeading: { - textAlign: 'center', - }, videoContainer: { - height: LOBBY_VIDEO_VIEW_HEIGHT, - borderRadius: 20, + height: landscape ? '40%' : '50%', + borderRadius: theme.variants.borderRadiusSizes.md, justifyContent: 'space-between', alignItems: 'center', overflow: 'hidden', - padding: 8, }, topView: {}, - bottomContainer: { - flex: 2, - justifyContent: 'space-evenly', - paddingHorizontal: 12, - }, participantStatusContainer: { alignSelf: 'flex-start', flexDirection: 'row', alignItems: 'center', - padding: 8, - borderRadius: 5, + padding: theme.variants.spacingSizes.sm, + borderTopRightRadius: theme.variants.borderRadiusSizes.sm, }, avatarContainer: { flex: 2, @@ -240,10 +203,7 @@ const useStyles = () => { userNameLabel: { flexShrink: 1, }, - audioMutedIconContainer: { - marginLeft: 8, - }, }), - [theme] + [theme, landscape] ); }; diff --git a/packages/react-native-sdk/src/components/Call/Lobby/LobbyFooter.tsx b/packages/react-native-sdk/src/components/Call/Lobby/LobbyFooter.tsx index 12973b064e..728f7a3388 100644 --- a/packages/react-native-sdk/src/components/Call/Lobby/LobbyFooter.tsx +++ b/packages/react-native-sdk/src/components/Call/Lobby/LobbyFooter.tsx @@ -1,12 +1,9 @@ -import React from 'react'; +import React, { useMemo } from 'react'; import { LobbyProps } from './Lobby'; import { View, StyleSheet, Text } from 'react-native'; -import { - useCall, - useCallStateHooks, - useI18n, -} from '@stream-io/video-react-bindings'; +import { useI18n } from '@stream-io/video-react-bindings'; import { useTheme } from '../../../contexts/ThemeContext'; +import { Lock } from '../../../icons/Lock'; /** * Props for the Lobby Footer in the Lobby component. @@ -24,42 +21,29 @@ export const LobbyFooter = ({ JoinCallButton, }: LobbyFooterProps) => { const { - theme: { colors, lobby, typefaces }, + theme: { colors, lobby, variants }, } = useTheme(); - const { useCallSession } = useCallStateHooks(); - const { t } = useI18n(); - - const call = useCall(); - const session = useCallSession(); - - const participantsCount = session?.participants.length; + const styles = useStyles(); return ( - - - {t('You are about to join a call with id {{ callId }}.', { - callId: call?.id, - }) + - ' ' + - (participantsCount - ? t('{{ numberOfParticipants }} participant(s) are in the call.', { - numberOfParticipants: participantsCount, - }) - : t('You are first to join the call.'))} - + + + + + + + {t( + "Start a private test call. This demo is built on Stream's SDKs and runs on our global edge network." + )} + + {JoinCallButton && ( )} @@ -67,9 +51,32 @@ export const LobbyFooter = ({ ); }; -const styles = StyleSheet.create({ - infoContainer: { - padding: 12, - borderRadius: 10, - }, -}); +const useStyles = () => { + const { theme } = useTheme(); + return useMemo( + () => + StyleSheet.create({ + mainContainer: { + padding: theme.variants.spacingSizes.sm, + }, + textContainer: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + backgroundColor: theme.colors.sheetTertiary, + paddingHorizontal: theme.variants.spacingSizes.md, + paddingVertical: theme.variants.spacingSizes.xs, + borderRadius: theme.variants.borderRadiusSizes.sm, + }, + iconContainer: { + marginRight: theme.variants.spacingSizes.sm, + }, + infoText: { + fontSize: theme.variants.fontSizes.sm, + lineHeight: 20, + fontWeight: '400', + }, + }), + [theme] + ); +}; diff --git a/packages/react-native-sdk/src/components/Call/RingingCallContent/IncomingCall.tsx b/packages/react-native-sdk/src/components/Call/RingingCallContent/IncomingCall.tsx index 074768c24e..40f874378f 100644 --- a/packages/react-native-sdk/src/components/Call/RingingCallContent/IncomingCall.tsx +++ b/packages/react-native-sdk/src/components/Call/RingingCallContent/IncomingCall.tsx @@ -71,7 +71,7 @@ export const IncomingCall = ({ @@ -136,7 +136,7 @@ const Background: React.FunctionComponent<{ diff --git a/packages/react-native-sdk/src/components/Call/RingingCallContent/OutgoingCall.tsx b/packages/react-native-sdk/src/components/Call/RingingCallContent/OutgoingCall.tsx index fe441098d4..6b5646397c 100644 --- a/packages/react-native-sdk/src/components/Call/RingingCallContent/OutgoingCall.tsx +++ b/packages/react-native-sdk/src/components/Call/RingingCallContent/OutgoingCall.tsx @@ -70,7 +70,7 @@ export const OutgoingCall = ({ { @@ -121,7 +121,7 @@ const Background = () => { diff --git a/packages/react-native-sdk/src/components/Call/RingingCallContent/TextBasedIndicator.tsx b/packages/react-native-sdk/src/components/Call/RingingCallContent/TextBasedIndicator.tsx index d4f1f4de53..d83fd1df7c 100644 --- a/packages/react-native-sdk/src/components/Call/RingingCallContent/TextBasedIndicator.tsx +++ b/packages/react-native-sdk/src/components/Call/RingingCallContent/TextBasedIndicator.tsx @@ -18,7 +18,7 @@ export const TextBasedIndicator = (props: TextBasedIndicatorProps) => { } = useTheme(); return ( - + {props.onBackPress && ( { }, ]} > - + )} {props.text} diff --git a/packages/react-native-sdk/src/components/Call/RingingCallContent/UserInfo.tsx b/packages/react-native-sdk/src/components/Call/RingingCallContent/UserInfo.tsx index 74a6c0e1ae..d3b111ca26 100644 --- a/packages/react-native-sdk/src/components/Call/RingingCallContent/UserInfo.tsx +++ b/packages/react-native-sdk/src/components/Call/RingingCallContent/UserInfo.tsx @@ -109,7 +109,7 @@ export const UserInfo = ({ style={[ styles.name, fontStyleByMembersCount, - { color: colors.base1 }, + { color: colors.typePrimary }, userInfo.name, ]} > diff --git a/packages/react-native-sdk/src/components/Livestream/HostLivestream/HostLivestream.tsx b/packages/react-native-sdk/src/components/Livestream/HostLivestream/HostLivestream.tsx index b18c4dfe9a..68d576dba9 100644 --- a/packages/react-native-sdk/src/components/Livestream/HostLivestream/HostLivestream.tsx +++ b/packages/react-native-sdk/src/components/Livestream/HostLivestream/HostLivestream.tsx @@ -108,9 +108,7 @@ export const HostLivestream = ({ diff --git a/packages/react-native-sdk/src/components/Livestream/LivestreamControls/HostLivestreamControls.tsx b/packages/react-native-sdk/src/components/Livestream/LivestreamControls/HostLivestreamControls.tsx index d3a1c35ad8..7f4d77f243 100644 --- a/packages/react-native-sdk/src/components/Livestream/LivestreamControls/HostLivestreamControls.tsx +++ b/packages/react-native-sdk/src/components/Livestream/LivestreamControls/HostLivestreamControls.tsx @@ -45,7 +45,7 @@ export const HostLivestreamControls = ({ diff --git a/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamAudioControlButton.tsx b/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamAudioControlButton.tsx index 005d542298..b03827b1d1 100644 --- a/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamAudioControlButton.tsx +++ b/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamAudioControlButton.tsx @@ -2,7 +2,7 @@ import { useCallStateHooks } from '@stream-io/video-react-bindings'; import React from 'react'; import { useTheme } from '../../../contexts'; import { Pressable, StyleSheet, View } from 'react-native'; -import { Mic, MicOff } from '../../../icons'; +import { IconWrapper, Mic, MicOff } from '../../../icons'; /** * The LivestreamAudioControlButton controls the audio stream publish/unpublish while in the livestream for the host. @@ -15,7 +15,6 @@ export const LivestreamAudioControlButton = () => { colors, variants: { iconSizes, buttonSizes }, livestreamAudioControlButton, - defaults, }, } = useTheme(); @@ -29,7 +28,7 @@ export const LivestreamAudioControlButton = () => { style={[ styles.container, { - backgroundColor: colors.background2, + backgroundColor: colors.buttonSecondaryDefault, height: buttonSizes.xs, width: buttonSizes.xs, }, @@ -46,11 +45,13 @@ export const LivestreamAudioControlButton = () => { livestreamAudioControlButton.icon, ]} > - {!optimisticIsMute ? ( - - ) : ( - - )} + + {!optimisticIsMute ? ( + + ) : ( + + )} + ); diff --git a/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamVideoControlButton.tsx b/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamVideoControlButton.tsx index e73f6c7a84..d34b215e10 100644 --- a/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamVideoControlButton.tsx +++ b/packages/react-native-sdk/src/components/Livestream/LivestreamControls/LivestreamVideoControlButton.tsx @@ -2,7 +2,7 @@ import { useCallStateHooks } from '@stream-io/video-react-bindings'; import React from 'react'; import { useTheme } from '../../../contexts'; import { Pressable, StyleSheet, View } from 'react-native'; -import { Video, VideoSlash } from '../../../icons'; +import { IconWrapper, Video, VideoSlash } from '../../../icons'; /** * The LivestreamVideoControlButton controls the video stream publish/unpublish while in the livestream for the host. @@ -17,7 +17,6 @@ export const LivestreamVideoControlButton = () => { colors, variants: { iconSizes, buttonSizes }, livestreamVideoControlButton, - defaults, }, } = useTheme(); @@ -35,7 +34,7 @@ export const LivestreamVideoControlButton = () => { style={[ styles.container, { - backgroundColor: colors.background2, + backgroundColor: colors.buttonSecondaryDefault, height: buttonSizes.xs, width: buttonSizes.xs, }, @@ -52,11 +51,13 @@ export const LivestreamVideoControlButton = () => { livestreamVideoControlButton.icon, ]} > - {!optimisticIsMute ? ( - ); diff --git a/packages/react-native-sdk/src/components/Livestream/LivestreamControls/ViewerLeaveStreamButton.tsx b/packages/react-native-sdk/src/components/Livestream/LivestreamControls/ViewerLeaveStreamButton.tsx index 2ded12c0a6..e32119a850 100644 --- a/packages/react-native-sdk/src/components/Livestream/LivestreamControls/ViewerLeaveStreamButton.tsx +++ b/packages/react-native-sdk/src/components/Livestream/LivestreamControls/ViewerLeaveStreamButton.tsx @@ -59,9 +59,7 @@ export const ViewerLeaveStreamButton = ({ diff --git a/packages/react-native-sdk/src/components/Livestream/LivestreamControls/ViewerLivestreamControls.tsx b/packages/react-native-sdk/src/components/Livestream/LivestreamControls/ViewerLivestreamControls.tsx index 268fec32d6..a212dc38b5 100644 --- a/packages/react-native-sdk/src/components/Livestream/LivestreamControls/ViewerLivestreamControls.tsx +++ b/packages/react-native-sdk/src/components/Livestream/LivestreamControls/ViewerLivestreamControls.tsx @@ -35,9 +35,7 @@ export const ViewerLivestreamControls = ({ diff --git a/packages/react-native-sdk/src/components/Livestream/LivestreamTopView/DurationBadge.tsx b/packages/react-native-sdk/src/components/Livestream/LivestreamTopView/DurationBadge.tsx index c5c0e8a10d..8d590836d5 100644 --- a/packages/react-native-sdk/src/components/Livestream/LivestreamTopView/DurationBadge.tsx +++ b/packages/react-native-sdk/src/components/Livestream/LivestreamTopView/DurationBadge.tsx @@ -120,7 +120,7 @@ export const DurationBadge = ({ mode }: DurationBadgeProps) => { @@ -137,7 +137,11 @@ export const DurationBadge = ({ mode }: DurationBadgeProps) => { {formatDuration(duration)} diff --git a/packages/react-native-sdk/src/components/Livestream/LivestreamTopView/FollowerCount.tsx b/packages/react-native-sdk/src/components/Livestream/LivestreamTopView/FollowerCount.tsx index 5e0435ab2c..ce0cbfdf1f 100644 --- a/packages/react-native-sdk/src/components/Livestream/LivestreamTopView/FollowerCount.tsx +++ b/packages/react-native-sdk/src/components/Livestream/LivestreamTopView/FollowerCount.tsx @@ -26,7 +26,7 @@ export const FollowerCount = ({}: FollowerCountProps) => { @@ -40,7 +40,11 @@ export const FollowerCount = ({}: FollowerCountProps) => { {totalParticipants} diff --git a/packages/react-native-sdk/src/components/Livestream/LivestreamTopView/HostLivestreamTopView.tsx b/packages/react-native-sdk/src/components/Livestream/LivestreamTopView/HostLivestreamTopView.tsx index e923ea7307..8e9b155ca7 100644 --- a/packages/react-native-sdk/src/components/Livestream/LivestreamTopView/HostLivestreamTopView.tsx +++ b/packages/react-native-sdk/src/components/Livestream/LivestreamTopView/HostLivestreamTopView.tsx @@ -57,7 +57,7 @@ export const HostLivestreamTopView = ({ { { - + ); @@ -171,9 +171,7 @@ export const FloatingParticipantView = ({ style={[ styles.participantViewContainer, participantViewStyle, - { - shadowColor: colors.base5, - }, + { shadowColor: colors.sheetPrimary }, floatingParticipantsView.participantViewContainer, ]} // video z order must be one above the one used in grid view @@ -193,7 +191,6 @@ export const FloatingParticipantView = ({ const styles = StyleSheet.create({ container: { - margin: 8, // Needed to make the view on top and draggable zIndex: Z_INDEX.IN_MIDDLE, flex: 1, diff --git a/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantLabel.tsx b/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantLabel.tsx index a226b41b1b..7ac0d6d1b1 100644 --- a/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantLabel.tsx +++ b/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantLabel.tsx @@ -76,7 +76,7 @@ export const ParticipantLabel = ({ - + {isPinningEnabled && ( @@ -146,7 +146,7 @@ const useStyles = () => { marginTop: 2, fontSize: 13, fontWeight: '400', - color: theme.colors.iconPrimaryDefault, + color: theme.colors.typePrimary, }, screenShareIconContainer: { marginRight: theme.variants.spacingSizes.sm, diff --git a/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantReaction.tsx b/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantReaction.tsx index cac5d2af64..053f2739ed 100644 --- a/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantReaction.tsx +++ b/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantReaction.tsx @@ -59,9 +59,11 @@ export const ParticipantReaction = ({ return ( currentReaction?.icon != null && ( - - {currentReaction?.icon} - + + + {currentReaction?.icon} + + ) ); @@ -73,16 +75,19 @@ const useStyles = () => { () => StyleSheet.create({ container: { + flex: 1, + zIndex: Z_INDEX.IN_FRONT, + }, + reaction: { + borderRadius: theme.variants.borderRadiusSizes.sm, + backgroundColor: theme.colors.sheetOverlay, alignSelf: 'flex-end', marginRight: theme.variants.spacingSizes.md, marginTop: theme.variants.spacingSizes.md, height: theme.variants.roundButtonSizes.md, width: theme.variants.roundButtonSizes.md, - borderRadius: theme.variants.borderRadiusSizes.sm, - backgroundColor: theme.colors.sheetOverlay, alignItems: 'center', justifyContent: 'center', - zIndex: Z_INDEX.IN_FRONT, }, }), [theme] diff --git a/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantVideoFallback.tsx b/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantVideoFallback.tsx index 1876085007..78ca55cde9 100644 --- a/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantVideoFallback.tsx +++ b/packages/react-native-sdk/src/components/Participant/ParticipantView/ParticipantVideoFallback.tsx @@ -29,18 +29,14 @@ export const ParticipantVideoFallback = ({ {!image ? ( { () => StyleSheet.create({ container: { - justifyContent: 'space-between', overflow: 'hidden', + justifyContent: 'flex-end', borderRadius: theme.variants.borderRadiusSizes.md, }, footerContainer: { diff --git a/packages/react-native-sdk/src/components/utility/Avatar.tsx b/packages/react-native-sdk/src/components/utility/Avatar.tsx index b572ac18e9..4f7757fb03 100644 --- a/packages/react-native-sdk/src/components/utility/Avatar.tsx +++ b/packages/react-native-sdk/src/components/utility/Avatar.tsx @@ -69,9 +69,7 @@ export const Avatar = (props: AvatarProps) => { height: size, width: size, }, - { - backgroundColor: colors.primary, - }, + { backgroundColor: colors.buttonPrimaryDefault }, avatar.container, styleProp?.container, ]} @@ -88,7 +86,7 @@ export const Avatar = (props: AvatarProps) => { { @@ -41,7 +41,7 @@ export const ScreenShareOverlay = ({}: ScreenShareOverlayProps) => { style={[ styles.text, typefaces.subtitleBold, - { color: colors.base1 }, + { color: colors.typePrimary }, screenshareOverlay.text, ]} > @@ -53,7 +53,7 @@ export const ScreenShareOverlay = ({}: ScreenShareOverlayProps) => { return [ styles.button, { - backgroundColor: colors.background2, + backgroundColor: colors.sheetSecondary, opacity: pressed ? 0.2 : 1, }, screenshareOverlay.button, @@ -75,7 +75,7 @@ export const ScreenShareOverlay = ({}: ScreenShareOverlayProps) => { diff --git a/packages/react-native-sdk/src/constants/index.ts b/packages/react-native-sdk/src/constants/index.ts index 67774527bb..c855d8a951 100644 --- a/packages/react-native-sdk/src/constants/index.ts +++ b/packages/react-native-sdk/src/constants/index.ts @@ -1,13 +1,11 @@ import { StreamReactionType } from '../components'; export const FLOATING_VIDEO_VIEW_STYLE = { - height: 140, - width: 80, + height: 170, + width: 100, borderRadius: 10, }; -export const LOBBY_VIDEO_VIEW_HEIGHT = 240; - export const defaultEmojiReactions: StreamReactionType[] = [ { type: 'reaction', diff --git a/packages/react-native-sdk/src/icons/Lock.tsx b/packages/react-native-sdk/src/icons/Lock.tsx new file mode 100644 index 0000000000..d5c2e7a26d --- /dev/null +++ b/packages/react-native-sdk/src/icons/Lock.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import Svg, { Path } from 'react-native-svg'; +import { ColorValue } from 'react-native/types'; + +type Props = { + color: ColorValue; + size: number; +}; + +export const Lock = ({ color, size }: Props) => { + return ( + + + + ); +}; diff --git a/packages/react-native-sdk/src/icons/Mic.tsx b/packages/react-native-sdk/src/icons/Mic.tsx index e46bd03c20..684c5233cb 100644 --- a/packages/react-native-sdk/src/icons/Mic.tsx +++ b/packages/react-native-sdk/src/icons/Mic.tsx @@ -8,7 +8,7 @@ type Props = { }; export const Mic = ({ color, size }: Props) => ( - + ( - + ( - + ( - + ( diff --git a/packages/react-native-sdk/src/theme/colors.ts b/packages/react-native-sdk/src/theme/colors.ts index f2861e2e1b..34f98d81cc 100644 --- a/packages/react-native-sdk/src/theme/colors.ts +++ b/packages/react-native-sdk/src/theme/colors.ts @@ -1,85 +1,24 @@ -import { palette } from './constants'; import { ColorScheme } from './types'; -const opacityToHex = (opacity: number) => { - return Math.round(opacity * 255) - .toString(16) - .padStart(2, '0'); -}; - const colors: ColorScheme = { - primary: palette.blue500, // remove and replace with primary100 - error: palette.red400, // remove and replace with warning100 - info: palette.green500, // remove and replace with success100 - disabled: palette.grey600, // remove and replace with primary180 - - // these are legacy and should be removed after Design v2 completed - base1: palette.grey50, - base2: palette.grey300, - base3: palette.grey500, - base4: palette.grey700, - base5: palette.grey950, - - // these are legacy and should be removed after Design v2 completed - background1: palette.grey950 + opacityToHex(0.05), - background2: palette.grey800, - background3: palette.grey950 + opacityToHex(0.4), - background4: palette.grey950 + opacityToHex(0.6), - background5: palette.grey900, - background6: palette.grey950 + opacityToHex(0.85), - - // Colors candidates for the default theme buttonPrimaryDefault: '#005fff', + buttonPrimaryDisabled: '#1b2c43', buttonSecondaryDefault: '#19232d', + buttonSecondaryHover: '#323b44', buttonSecondaryWarningDefault: '#dc433b', + iconPrimaryDefault: '#eff0f1', + iconPrimaryAccent: '#005fff', iconAlertSuccess: '#00e2a1', + iconAlertWarning: '#dc433b', + sheetPrimary: '#000000', + sheetSecondary: '#101213', + sheetTertiary: '#19232d', sheetOverlay: '#0c0d0ea6', + typePrimary: '#eff0f1', typeSecondary: '#b0b4b7', - buttonSecondaryHover: '#323b44', - - buttonPrimaryDisabled: '#1b2c43', - buttonPrimaryHover: '#4c8fff', - buttonPrimaryPressed: '#123d82', - buttonQuaternaryActive: '#19232d', - buttonQuaternaryDefault: '#dc433b', - buttonQuaternaryDisabled: '#31292f', - buttonQuaternaryHover: '#e77b76', - buttonQuaternaryPressed: '#7d3535', - buttonSecondaryDisabled: '#1e262e29', - buttonSecondaryPressed: '#101213', - buttonSecondaryActiveDefault: '#005fff', - buttonSecondaryActiveHover: '#4c8fff', - buttonSecondaryActivePressed: '#123d82', - buttonSecondaryWarningHover: '#e77b76', - buttonSecondaryWarningPressed: '#7d3535', - buttonTertiaryActive: '#19232d', - buttonTertiaryDisabled: '#1e262e29', - buttonTertiaryHover: '#4c535b', - buttonTertiaryPressed: '#101213', - buttonTertiaryStroke: '#323b44', - containerCaution: '#353830', - containerNeutral: '#323b44', - containerPrimary: '#1b2c43', - containerSecondary: '#263942', - containerSuccess: '#1d2f34', - containerTertiary: '#2d3042', - containerWarning: '#31292f', - iconAlertCaution: '#ffd646', - iconAlertWarning: '#dc433b', - iconPrimaryAccent: '#005fff', - iconPrimaryDisabled: '#7e8389', - iconPrimaryHover: '#e3e4e5', - iconPrimaryOnAccent: '#eff0f1', - iconPrimaryPressed: '#656b72', - sheetSecondary: '#101213', - sheetTertiary: '#19232d', - typeAccent: '#00e2a1', - typeOnAccent: '#eff0f1', - typeQuaternary: '#101213', - typeTertiary: '#656b72', }; const colorPalette = { diff --git a/packages/react-native-sdk/src/theme/constants.ts b/packages/react-native-sdk/src/theme/constants.ts index c9c99171f5..2d28ef0559 100644 --- a/packages/react-native-sdk/src/theme/constants.ts +++ b/packages/react-native-sdk/src/theme/constants.ts @@ -1,51 +1,5 @@ const ref = { palette: { - // TODO: remove old palette colors and keep only new ones: primary, secondary... in design v2 - green50: '#F6FEF9', - green100: '#E9F1FF', - green200: '#A6F2C6', - green300: '#79ECA9', - green400: '#4CE68C', - green500: '#20E070', - green600: '#19B359', - green700: '#138643', - green800: '#0D592C', - green900: '#062D16', - green950: '#041B0D', - blue50: '#F5FAFF', - blue100: '#E0F0FF', - blue200: '#CCDFFF', - blue300: '#669FFF', - blue400: '#337EFF', - blue500: '#005FFF', - blue600: '#004CCC', - blue700: '#003999', - blue800: '#002666', - blue900: '#00163D', - blue950: '#000D24', - red50: '#FFF5F5', - red100: '#FFE5E7', - red200: '#FF999F', - red300: '#FF666E', - red400: '#FF3742', - red500: '#FF000E', - red600: '#CC000B', - red700: '#990008', - red800: '#660006', - red900: '#330003', - red950: '#1F0002', - grey50: '#FFFFFF', - grey100: '#F7F7F8', - grey200: '#E9EAED', - grey300: '#DBDDE1', - grey400: '#B4B7BB', - grey500: '#72767E', - grey600: '#4C525C', - grey700: '#272A30', - grey800: '#1C1E22', - grey900: '#121416', - grey950: '#080707', - primary100: '#005fff', primary150: '#123d82', primary180: '#1b2c43', diff --git a/packages/react-native-sdk/src/theme/theme.ts b/packages/react-native-sdk/src/theme/theme.ts index 3560e77198..75fa0c6231 100644 --- a/packages/react-native-sdk/src/theme/theme.ts +++ b/packages/react-native-sdk/src/theme/theme.ts @@ -380,15 +380,15 @@ export const defaultTheme: Theme = { }, }, defaults: { - color: colors.primary, - backgroundColor: colors.background2, + color: colors.buttonPrimaryDefault, + backgroundColor: colors.sheetPrimary, margin: 10, padding: 10, fontSize: 16, fontWeight: '500', borderRadius: 32, iconSize: 28, - borderColor: colors.primary, + borderColor: colors.buttonPrimaryDefault, borderWidth: 1, }, colors: colors, diff --git a/packages/react-native-sdk/src/theme/types.ts b/packages/react-native-sdk/src/theme/types.ts index 4c9c0db527..e74dd6bdff 100644 --- a/packages/react-native-sdk/src/theme/types.ts +++ b/packages/react-native-sdk/src/theme/types.ts @@ -1,76 +1,21 @@ import { ColorValue, TextStyle } from 'react-native'; export type ColorScheme = { - primary: ColorValue; - error: ColorValue; - info: ColorValue; - disabled: ColorValue; - - // TODO: remove these legacy colors when Design v2 rewrite is completed - base1: ColorValue; - base2: ColorValue; - base4: ColorValue; - base5: ColorValue; - - // TODO: remove these legacy colors when Design v2 rewrite is completed - background1: ColorValue; - background2: ColorValue; - background3: ColorValue; - background4: ColorValue; - background5: ColorValue; - background6: ColorValue; - - // TODO: when design v2 is complete, filter out the not used colors from here (expected to have ~15 theme colors) buttonPrimaryDefault: ColorValue; buttonPrimaryDisabled: ColorValue; - buttonPrimaryHover: ColorValue; - buttonPrimaryPressed: ColorValue; - buttonQuaternaryActive: ColorValue; - buttonQuaternaryDefault: ColorValue; - buttonQuaternaryDisabled: ColorValue; - buttonQuaternaryHover: ColorValue; - buttonQuaternaryPressed: ColorValue; buttonSecondaryDefault: ColorValue; - buttonSecondaryDisabled: ColorValue; buttonSecondaryHover: ColorValue; - buttonSecondaryPressed: ColorValue; - buttonSecondaryActiveDefault: ColorValue; - buttonSecondaryActiveHover: ColorValue; - buttonSecondaryActivePressed: ColorValue; buttonSecondaryWarningDefault: ColorValue; - buttonSecondaryWarningHover: ColorValue; - buttonSecondaryWarningPressed: ColorValue; - buttonTertiaryActive: ColorValue; - buttonTertiaryDisabled: ColorValue; - buttonTertiaryHover: ColorValue; - buttonTertiaryPressed: ColorValue; - buttonTertiaryStroke: ColorValue; - containerCaution: ColorValue; - containerNeutral: ColorValue; - containerPrimary: ColorValue; - containerSecondary: ColorValue; - containerSuccess: ColorValue; - containerTertiary: ColorValue; - containerWarning: ColorValue; - iconAlertCaution: ColorValue; + iconPrimaryDefault: ColorValue; + iconPrimaryAccent: ColorValue; iconAlertSuccess: ColorValue; iconAlertWarning: ColorValue; - iconPrimaryAccent: ColorValue; - iconPrimaryDefault: ColorValue; - iconPrimaryDisabled: ColorValue; - iconPrimaryHover: ColorValue; - iconPrimaryOnAccent: ColorValue; - iconPrimaryPressed: ColorValue; - sheetOverlay: ColorValue; sheetPrimary: ColorValue; sheetSecondary: ColorValue; sheetTertiary: ColorValue; - typeAccent: ColorValue; - typeOnAccent: ColorValue; + sheetOverlay: ColorValue; typePrimary: ColorValue; - typeQuaternary: ColorValue; typeSecondary: ColorValue; - typeTertiary: ColorValue; // allow any other color [key: string]: ColorValue; diff --git a/packages/react-native-sdk/src/translations/en.json b/packages/react-native-sdk/src/translations/en.json index 95888d78f4..eaf5fb1679 100644 --- a/packages/react-native-sdk/src/translations/en.json +++ b/packages/react-native-sdk/src/translations/en.json @@ -11,7 +11,7 @@ "End Stream": "End Stream", "Leave Stream": "Leave Stream", "Live": "Live", - "Before Joining": "Before Joining", + "Setup your test call": "Setup your test call", "Setup your audio and video": "Setup your audio and video", "Setup your audio": "Setup your audio", "You are first to Join the call.": "You are first to Join the call.", @@ -24,4 +24,4 @@ "You are about to join a call with id {{ callId }}.": "You are about to join a call with id {{ callId }}.", "Preparing call": "Preparing call", "You have left the call": "You have left the call" -} +} \ No newline at end of file diff --git a/sample-apps/react-native/dogfood/ios/StreamReactNativeVideoSDKSample.xcodeproj/project.pbxproj b/sample-apps/react-native/dogfood/ios/StreamReactNativeVideoSDKSample.xcodeproj/project.pbxproj index 8fc01b826e..c029f9ebc0 100644 --- a/sample-apps/react-native/dogfood/ios/StreamReactNativeVideoSDKSample.xcodeproj/project.pbxproj +++ b/sample-apps/react-native/dogfood/ios/StreamReactNativeVideoSDKSample.xcodeproj/project.pbxproj @@ -710,6 +710,7 @@ SWIFT_OBJC_BRIDGING_HEADER = "StreamReactNativeVideoSDKSample-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; }; name = Debug; @@ -815,6 +816,7 @@ PROVISIONING_PROFILE_SPECIFIER = "match AppStore io.getstream.rnvideosample"; SWIFT_OBJC_BRIDGING_HEADER = "StreamReactNativeVideoSDKSample-Bridging-Header.h"; SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; }; name = Release; @@ -906,6 +908,7 @@ ); REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; USE_HERMES = true; }; name = Debug; @@ -993,6 +996,7 @@ ); REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; USE_HERMES = true; VALIDATE_PRODUCT = YES; }; diff --git a/sample-apps/react-native/dogfood/src/assets/LightDark.tsx b/sample-apps/react-native/dogfood/src/assets/LightDark.tsx new file mode 100644 index 0000000000..f48ee64648 --- /dev/null +++ b/sample-apps/react-native/dogfood/src/assets/LightDark.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { Svg, Path } from 'react-native-svg'; +import { ColorValue } from 'react-native/types'; + +type Props = { + color: ColorValue; + size: number; +}; + +const LightDark = ({ color, size }: Props) => ( + + + +); + +export default LightDark; diff --git a/sample-apps/react-native/dogfood/src/components/BottomControlsDrawer.tsx b/sample-apps/react-native/dogfood/src/components/BottomControlsDrawer.tsx index 07f4e5dd18..0b817e762d 100644 --- a/sample-apps/react-native/dogfood/src/components/BottomControlsDrawer.tsx +++ b/sample-apps/react-native/dogfood/src/components/BottomControlsDrawer.tsx @@ -194,6 +194,7 @@ export const BottomControlsDrawer: React.FC = ({ transparent={true} visible={isVisible} onRequestClose={onClose} + supportedOrientations={['portrait', 'landscape']} > @@ -235,6 +236,7 @@ const useStyles = () => { borderTopRightRadius: variants.borderRadiusSizes.lg, padding: variants.spacingSizes.md, maxHeight: '80%', + maxWidth: 500, }, dragIndicator: { width: '100%', @@ -271,7 +273,8 @@ const useStyles = () => { option: { flexDirection: 'row', alignItems: 'center', - borderWidth: 2, + borderWidth: 1, + borderColor: colors.sheetTertiary, borderRadius: variants.borderRadiusSizes.lg, paddingHorizontal: variants.spacingSizes.md, height: variants.roundButtonSizes.lg, @@ -282,7 +285,8 @@ const useStyles = () => { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', - borderWidth: 2, + borderWidth: 1, + borderColor: colors.sheetTertiary, borderRadius: variants.borderRadiusSizes.lg, paddingHorizontal: variants.spacingSizes.md, height: variants.roundButtonSizes.lg, diff --git a/sample-apps/react-native/dogfood/src/components/Button.tsx b/sample-apps/react-native/dogfood/src/components/Button.tsx index 889a1dd01a..fe6f671f73 100644 --- a/sample-apps/react-native/dogfood/src/components/Button.tsx +++ b/sample-apps/react-native/dogfood/src/components/Button.tsx @@ -58,14 +58,14 @@ const useStyles = () => { () => StyleSheet.create({ button: { - backgroundColor: appTheme.colors.primary, + backgroundColor: appTheme.colors.buttonPrimaryDefault, justifyContent: 'center', borderRadius: 8, height: BUTTON_HEIGHT, paddingHorizontal: appTheme.variants.spacingSizes.md, }, buttonText: { - color: appTheme.colors.static_white, + color: appTheme.colors.iconPrimaryDefault, fontWeight: appTheme.typefaces.heading6.fontWeight, textAlign: 'center', fontSize: 17, diff --git a/sample-apps/react-native/dogfood/src/components/CallControlls/BottomControls.tsx b/sample-apps/react-native/dogfood/src/components/CallControlls/BottomControls.tsx index 89a5a9411f..c6fe0a0fd3 100644 --- a/sample-apps/react-native/dogfood/src/components/CallControlls/BottomControls.tsx +++ b/sample-apps/react-native/dogfood/src/components/CallControlls/BottomControls.tsx @@ -8,7 +8,6 @@ import { } from '@stream-io/video-react-native-sdk'; import React, { useMemo } from 'react'; import { StyleSheet, Text, View } from 'react-native'; -import { appTheme } from '../../theme'; import { BOTTOM_CONTROLS_HEIGHT, Z_INDEX } from '../../constants'; import { MoreActionsButton } from './MoreActionsButton'; import { ParticipantsButton } from './ParticipantsButton'; @@ -83,12 +82,12 @@ const useStyles = (showMicLabel: boolean) => { height: BOTTOM_CONTROLS_HEIGHT, }, speakingLabelContainer: { - backgroundColor: appTheme.colors.static_overlay, + backgroundColor: theme.colors.sheetSecondary, width: '100%', }, label: { textAlign: 'center', - color: appTheme.colors.static_white, + color: theme.colors.typePrimary, }, callControlsWrapper: { display: 'flex', diff --git a/sample-apps/react-native/dogfood/src/components/CallControlls/CallRecordingModal.tsx b/sample-apps/react-native/dogfood/src/components/CallControlls/CallRecordingModal.tsx index 97ec6896fd..a8ea2c2bcf 100644 --- a/sample-apps/react-native/dogfood/src/components/CallControlls/CallRecordingModal.tsx +++ b/sample-apps/react-native/dogfood/src/components/CallControlls/CallRecordingModal.tsx @@ -45,6 +45,7 @@ export const CallRecordingModal: React.FC = ({ transparent={true} visible={visible} onRequestClose={onCancel} + supportedOrientations={['portrait', 'landscape']} > @@ -155,7 +156,7 @@ const useStyles = (isEndRecordingModal: boolean) => { : theme.colors.buttonPrimaryDefault, }, buttonText: { - color: 'white', + color: theme.colors.typePrimary, fontSize: 13, fontWeight: '600', }, diff --git a/sample-apps/react-native/dogfood/src/components/CallControlls/LayoutSwitcherButton.tsx b/sample-apps/react-native/dogfood/src/components/CallControlls/LayoutSwitcherButton.tsx index e2e9881f7a..8abe3bd774 100644 --- a/sample-apps/react-native/dogfood/src/components/CallControlls/LayoutSwitcherButton.tsx +++ b/sample-apps/react-native/dogfood/src/components/CallControlls/LayoutSwitcherButton.tsx @@ -63,7 +63,7 @@ export const LayoutSwitcherButton = ({ return ( { handleOpenModal(); diff --git a/sample-apps/react-native/dogfood/src/components/CallControlls/LayoutSwitcherModal.tsx b/sample-apps/react-native/dogfood/src/components/CallControlls/LayoutSwitcherModal.tsx index cd7744e911..cfaa31ccf7 100644 --- a/sample-apps/react-native/dogfood/src/components/CallControlls/LayoutSwitcherModal.tsx +++ b/sample-apps/react-native/dogfood/src/components/CallControlls/LayoutSwitcherModal.tsx @@ -40,9 +40,8 @@ const LayoutSwitcherModal: React.FC = ({ if (isVisible && anchorPosition) { const windowHeight = Dimensions.get('window').height; const windowWidth = Dimensions.get('window').width; - let top = anchorPosition.y + anchorPosition.height / 2 + topInset; - let left = anchorPosition.x + leftInset; + let left = anchorPosition.x + leftInset + 6; // Ensure the popup stays within the screen bounds if (top + 150 > windowHeight) { @@ -88,7 +87,7 @@ const LayoutSwitcherModal: React.FC = ({ > Grid @@ -124,13 +123,15 @@ const useStyles = () => { position: 'absolute', width: 212, backgroundColor: theme.colors.sheetSecondary, - borderRadius: theme.variants.borderRadiusSizes.lg, + borderRadius: theme.variants.borderRadiusSizes.md, padding: theme.variants.spacingSizes.md, gap: theme.variants.spacingSizes.sm, }, button: { backgroundColor: theme.colors.buttonSecondaryDefault, borderRadius: theme.variants.borderRadiusSizes.lg, + borderWidth: 1, + borderColor: theme.colors.sheetTertiary, flexDirection: 'row', justifyContent: 'flex-start', alignItems: 'center', @@ -138,10 +139,10 @@ const useStyles = () => { paddingVertical: theme.variants.spacingSizes.sm, }, selectedButton: { - backgroundColor: theme.colors.primary, + backgroundColor: theme.colors.buttonPrimaryDefault, }, buttonText: { - color: 'white', + color: theme.colors.typePrimary, textAlign: 'center', fontWeight: '600', marginTop: 2, diff --git a/sample-apps/react-native/dogfood/src/components/CallControlls/MoreActionsButton.tsx b/sample-apps/react-native/dogfood/src/components/CallControlls/MoreActionsButton.tsx index 172114b3ee..29019e0695 100644 --- a/sample-apps/react-native/dogfood/src/components/CallControlls/MoreActionsButton.tsx +++ b/sample-apps/react-native/dogfood/src/components/CallControlls/MoreActionsButton.tsx @@ -7,9 +7,14 @@ import { import { IconWrapper } from '@stream-io/video-react-native-sdk/src/icons'; import MoreActions from '../../assets/MoreActions'; import { BottomControlsDrawer, DrawerOption } from '../BottomControlsDrawer'; -import Stats from '../../assets/Stats'; import Feedback from '../../assets/Feedback'; import FeedbackModal from '../FeedbackModal'; +import { + ThemeMode, + useAppGlobalStoreSetState, + useAppGlobalStoreValue, +} from '../../contexts/AppContext'; +import LightDark from '../../assets/LightDark'; /** * The props for the More Actions Button in the Call Controls. @@ -34,6 +39,8 @@ export const MoreActionsButton = ({ } = useTheme(); const [isDrawerVisible, setIsDrawerVisible] = useState(false); const [feedbackModalVisible, setFeedbackModalVisible] = useState(false); + const setState = useAppGlobalStoreSetState(); + const themeMode = useAppGlobalStoreValue((store) => store.themeMode); const call = useCall(); const handleRating = async (rating: number) => { @@ -46,34 +53,48 @@ export const MoreActionsButton = ({ setFeedbackModalVisible(false); }; + const getName = (theme: ThemeMode) => { + if (theme === 'light') { + return 'Dark mode'; + } + return 'Light mode'; + }; + const options: DrawerOption[] = [ { id: '1', - label: 'Stats', + label: 'Feedback', icon: ( - ), - onPress: () => {}, + onPress: () => { + setIsDrawerVisible(false); + setFeedbackModalVisible(true); + }, }, { id: '2', - label: 'Feedback', + label: getName(themeMode), icon: ( - ), onPress: () => { + if (themeMode === 'light') { + setState({ themeMode: 'dark' }); + } else { + setState({ themeMode: 'light' }); + } setIsDrawerVisible(false); - setFeedbackModalVisible(true); }, }, ]; diff --git a/sample-apps/react-native/dogfood/src/components/CallControlls/TopControls.tsx b/sample-apps/react-native/dogfood/src/components/CallControlls/TopControls.tsx index 29e1904eb2..787d930359 100644 --- a/sample-apps/react-native/dogfood/src/components/CallControlls/TopControls.tsx +++ b/sample-apps/react-native/dogfood/src/components/CallControlls/TopControls.tsx @@ -9,6 +9,7 @@ import { import { CallStatusBadge } from './CallStatusBadge'; import { VideoEffectsButton } from '../VideoEffectsButton'; import { LayoutSwitcherButton } from './LayoutSwitcherButton'; +import { useOrientation } from '../../hooks/useOrientation'; export type TopControlsProps = { onHangupCallHandler?: () => void; @@ -24,6 +25,9 @@ export const TopControls = ({ const [topControlsHeight, setTopControlsHeight] = useState(0); const [topControlsWidth, setTopControlsWidth] = useState(0); const styles = useStyles(); + const { theme } = useTheme(); + const orientation = useOrientation(); + const isLandscape = orientation === 'landscape'; const onLayout: React.ComponentProps['onLayout'] = (event) => { const { height, width } = event.nativeEvent.layout; @@ -41,8 +45,10 @@ export const TopControls = ({ - - {!isAwaitingResponse && } + + {(!isAwaitingResponse || isLandscape) && } diff --git a/sample-apps/react-native/dogfood/src/components/FeedbackModal.tsx b/sample-apps/react-native/dogfood/src/components/FeedbackModal.tsx index 511a8b8c9e..086a2dfb70 100644 --- a/sample-apps/react-native/dogfood/src/components/FeedbackModal.tsx +++ b/sample-apps/react-native/dogfood/src/components/FeedbackModal.tsx @@ -151,7 +151,7 @@ const useStyles = () => { fontSize: 28, marginBottom: variants.spacingSizes.sm, textAlign: 'center', - color: 'white', + color: colors.typePrimary, fontWeight: '600', }, subtitle: { diff --git a/sample-apps/react-native/dogfood/src/components/LobbyViewComponent.tsx b/sample-apps/react-native/dogfood/src/components/LobbyViewComponent.tsx index e8370c6206..bf7848ff91 100644 --- a/sample-apps/react-native/dogfood/src/components/LobbyViewComponent.tsx +++ b/sample-apps/react-native/dogfood/src/components/LobbyViewComponent.tsx @@ -31,18 +31,7 @@ export const LobbyViewComponent = ({ return ( <> - {route.name === 'MeetingScreen' ? ( - { - navigation.navigate('GuestModeScreen', { callId }); - }} - > - - {t('Join as Guest or Anonymously')} - - - ) : ( + {route.name !== 'MeetingScreen' && ( { diff --git a/sample-apps/react-native/dogfood/src/components/NavigationHeader.tsx b/sample-apps/react-native/dogfood/src/components/NavigationHeader.tsx index a08d99c031..ca1659ee6f 100755 --- a/sample-apps/react-native/dogfood/src/components/NavigationHeader.tsx +++ b/sample-apps/react-native/dogfood/src/components/NavigationHeader.tsx @@ -3,8 +3,9 @@ import { StreamVideoRN, useI18n, useStreamVideoClient, + useTheme, } from '@stream-io/video-react-native-sdk'; -import React from 'react'; +import React, { useMemo } from 'react'; import { Alert, StyleSheet, Text } from 'react-native'; import { useAppGlobalStoreSetState, @@ -21,6 +22,7 @@ import { REACT_NATIVE_DOGFOOD_APP_ENVIRONMENT } from '@env'; export const NavigationHeader = ({ route }: NativeStackHeaderProps) => { const videoClient = useStreamVideoClient(); const { t } = useI18n(); + const styles = useStyles(); const userName = useAppGlobalStoreValue((store) => store.userName); const appStoreSetState = useAppGlobalStoreSetState(); @@ -91,41 +93,48 @@ export const NavigationHeader = ({ route }: NativeStackHeaderProps) => { ); }; -const styles = StyleSheet.create({ - header: { - width: '100%', - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'space-between', - paddingHorizontal: appTheme.spacing.lg, - paddingVertical: appTheme.spacing.lg, - backgroundColor: appTheme.colors.static_grey, - shadowColor: '#000', - shadowOffset: { - width: 0, - height: 2, - }, - shadowOpacity: 0.23, - shadowRadius: 2.62, +const useStyles = () => { + const { theme } = useTheme(); + return useMemo( + () => + StyleSheet.create({ + header: { + width: '100%', + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + paddingHorizontal: appTheme.spacing.lg, + paddingVertical: appTheme.spacing.lg, + backgroundColor: theme.colors.sheetSecondary, + shadowColor: '#000', + shadowOffset: { + width: 0, + height: 2, + }, + shadowOpacity: 0.23, + shadowRadius: 2.62, - elevation: 4, - }, - headerText: { - flexShrink: 1, - fontSize: 20, - fontWeight: '500', - color: appTheme.colors.static_white, - marginRight: appTheme.spacing.lg, - }, - avatar: { - height: AVATAR_SIZE, - width: AVATAR_SIZE, - borderRadius: 50, - }, - chooseAppMode: { - fontWeight: 'bold', - }, - buttonText: { - fontSize: 12, - }, -}); + elevation: 4, + }, + headerText: { + flexShrink: 1, + fontSize: 20, + fontWeight: '500', + color: theme.colors.typePrimary, + marginRight: appTheme.spacing.lg, + }, + avatar: { + height: AVATAR_SIZE, + width: AVATAR_SIZE, + borderRadius: 50, + }, + chooseAppMode: { + fontWeight: 'bold', + }, + buttonText: { + fontSize: 12, + }, + }), + [theme], + ); +}; diff --git a/sample-apps/react-native/dogfood/src/components/ParticipantActions.tsx b/sample-apps/react-native/dogfood/src/components/ParticipantActions.tsx index 7b45e84436..0479c7d57b 100644 --- a/sample-apps/react-native/dogfood/src/components/ParticipantActions.tsx +++ b/sample-apps/react-native/dogfood/src/components/ParticipantActions.tsx @@ -7,6 +7,7 @@ import { useCall, useCallStateHooks, useI18n, + useTheme, } from '@stream-io/video-react-native-sdk'; import { Cross } from '../assets/Cross'; import { Mic } from '../assets/Mic'; @@ -19,7 +20,6 @@ import { VideoSlash } from '../assets/VideoSlash'; import { Pressable, StyleSheet, Text, View } from 'react-native'; import React, { useCallback, useMemo } from 'react'; import { generateParticipantTitle } from '../utils'; -import { useTheme } from 'stream-chat-react-native'; type CallParticipantOptionType = { title: string; @@ -103,7 +103,7 @@ export const ParticipantActions = (props: ParticipantActionsType) => { const muteUserVideoOption = participantPublishesVideo ? { - icon: , + icon: , title: 'Mute Video', onPressHandler: muteUserVideo, } @@ -111,7 +111,7 @@ export const ParticipantActions = (props: ParticipantActionsType) => { const muteUserAudioOption = participantPublishesAudio ? { - icon: , + icon: , title: 'Mute Audio', onPressHandler: muteUserAudio, } @@ -125,37 +125,37 @@ export const ParticipantActions = (props: ParticipantActionsType) => { userHasUpdateCallPermissionsCapability ? [ { - icon: , + icon: , title: 'Disable Video', onPressHandler: async () => await revokePermission(OwnCapability.SEND_VIDEO), }, { - icon: , + icon: , title: 'Disable Audio', onPressHandler: async () => await revokePermission(OwnCapability.SEND_AUDIO), }, { - icon: , + icon: , title: 'Allow Audio', onPressHandler: async () => await grantPermission(OwnCapability.SEND_AUDIO), }, { - icon: , + icon: , title: 'Allow Video', onPressHandler: async () => await grantPermission(OwnCapability.SEND_VIDEO), }, { - icon: , + icon: , title: 'Allow Screen Sharing', onPressHandler: async () => await grantPermission(OwnCapability.SCREENSHARE), }, { - icon: , + icon: , title: 'Disable Screen Sharing', onPressHandler: async () => await revokePermission(OwnCapability.SCREENSHARE), @@ -167,7 +167,7 @@ export const ParticipantActions = (props: ParticipantActionsType) => { userHasBlockUserCapability ? [ { - icon: , + icon: , title: 'Block', onPressHandler: blockUser, }, @@ -177,7 +177,7 @@ export const ParticipantActions = (props: ParticipantActionsType) => { const isLocalPinningAllowed = !participant.pin || participant.pin.isLocalPin; const pinParticipant: CallParticipantOptionType | null = isLocalPinningAllowed ? { - icon: , + icon: , title: participant.pin ? 'Unpin' : 'Pin', onPressHandler: toggleParticipantPinnedAt, } @@ -191,7 +191,6 @@ export const ParticipantActions = (props: ParticipantActionsType) => { ]; const showYouLabel = participant.isLocalParticipant; - return ( @@ -207,7 +206,7 @@ export const ParticipantActions = (props: ParticipantActionsType) => { style={styles.closePressable} onPress={onCloseParticipantOptions} > - + {options.map((option, index) => { @@ -248,7 +247,7 @@ const useStyles = () => { flex: 1, }, modalContainer: { - backgroundColor: theme.colors.background5, + backgroundColor: theme.colors.sheetPrimary, borderRadius: 15, marginHorizontal: 32, }, @@ -266,7 +265,7 @@ const useStyles = () => { marginLeft: 8, fontSize: 16, fontWeight: '500', - color: theme.colors.base1, + color: theme.colors.iconPrimaryDefault, }, option: { paddingHorizontal: 24, @@ -280,12 +279,12 @@ const useStyles = () => { }, title: { marginLeft: 16, - color: theme.colors.base1, + color: theme.colors.iconPrimaryDefault, fontSize: 16, fontWeight: '400', }, borderBottom: { - borderBottomColor: theme.colors.base4, + borderBottomColor: theme.colors.buttonSecondaryHover, borderBottomWidth: 1, }, crossIcon: { @@ -294,8 +293,8 @@ const useStyles = () => { }, closePressable: { padding: 8, - borderRadius: 5, - backgroundColor: theme.colors.base4, + borderRadius: 15, + backgroundColor: theme.colors.buttonSecondaryDefault, }, }), [theme], diff --git a/sample-apps/react-native/dogfood/src/components/ParticipantsInfoList.tsx b/sample-apps/react-native/dogfood/src/components/ParticipantsInfoList.tsx index b7a4743d76..f64d178655 100644 --- a/sample-apps/react-native/dogfood/src/components/ParticipantsInfoList.tsx +++ b/sample-apps/react-native/dogfood/src/components/ParticipantsInfoList.tsx @@ -29,7 +29,6 @@ import { MicOff } from '../assets/MicOff'; import { ScreenShare } from '../assets/ScreenShare'; import { VideoSlash } from '../assets/VideoSlash'; import { ArrowRight } from '../assets/ArrowRight'; -import { appTheme } from '../theme'; import { ParticipantActions } from './ParticipantActions'; import { generateParticipantTitle } from '../utils'; import { Z_INDEX } from '../constants'; @@ -58,6 +57,7 @@ export const ParticipantsInfoList = ({ setIsCallParticipantsInfoVisible, }: ParticipantsInfoListProps) => { const styles = useStyles(); + const { theme } = useTheme(); const { useParticipants } = useCallStateHooks(); const participants = useParticipants(); const { t } = useI18n(); @@ -129,14 +129,14 @@ export const ParticipantsInfoList = ({ testID={ButtonTestIds.EXIT_PARTICIPANTS_INFO} > - + {t('Invite')} @@ -219,22 +219,22 @@ const ParticipantInfoItem = (props: ParticipantInfoType) => { - + )} {isAudioMuted && ( - + )} {isVideoMuted && ( - + )} {!participantIsLocalParticipant && ( - + )} @@ -249,14 +249,14 @@ const useStyles = () => { StyleSheet.create({ backDropBackground: { ...StyleSheet.absoluteFillObject, - backgroundColor: theme.colors.background3, zIndex: Z_INDEX.IN_BACK, }, content: { zIndex: Z_INDEX.IN_FRONT, - backgroundColor: theme.colors.background5, + backgroundColor: theme.colors.sheetPrimary, borderRadius: 15, marginHorizontal: 16, + marginTop: 65, }, header: { flexDirection: 'row', @@ -270,13 +270,13 @@ const useStyles = () => { headerText: { fontSize: 16, fontWeight: '600', - color: theme.base1, + color: theme.colors.typePrimary, }, closePressable: { padding: 8, - borderRadius: 5, + borderRadius: 15, marginRight: 16, - backgroundColor: theme.base4, + backgroundColor: theme.colors.buttonSecondaryDefault, }, buttonGroup: { flexDirection: 'row', @@ -298,14 +298,22 @@ const useStyles = () => { }, button: { flex: 1, - backgroundColor: theme.colors.primary, + borderRadius: 24, + padding: 8, + marginHorizontal: 8, + borderColor: theme.colors.buttonSecondaryDefault, + borderWidth: 2, + }, + inviteButton: { + flex: 1, + backgroundColor: theme.colors.buttonPrimaryDefault, borderRadius: 24, padding: 8, marginHorizontal: 8, }, buttonText: { textAlign: 'center', - color: theme.colors.base1, + color: theme.colors.iconPrimaryDefault, fontSize: 16, fontWeight: '500', }, @@ -315,7 +323,7 @@ const useStyles = () => { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', - borderBottomColor: theme.colors.base4, + borderBottomColor: theme.colors.buttonSecondaryHover, borderBottomWidth: 1, }, participantInfo: { @@ -325,7 +333,7 @@ const useStyles = () => { }, name: { marginLeft: 8, - color: theme.colors.base1, + color: theme.colors.typePrimary, flexShrink: 1, fontSize: 16, fontWeight: '500', @@ -339,7 +347,6 @@ const useStyles = () => { modal: { alignItems: 'center', justifyContent: 'center', - backgroundColor: theme.colors.background3, }, }), [theme], diff --git a/sample-apps/react-native/dogfood/src/components/TextInput.tsx b/sample-apps/react-native/dogfood/src/components/TextInput.tsx index ae41d4c038..198141db36 100644 --- a/sample-apps/react-native/dogfood/src/components/TextInput.tsx +++ b/sample-apps/react-native/dogfood/src/components/TextInput.tsx @@ -1,15 +1,20 @@ -import React from 'react'; +import React, { useMemo } from 'react'; import { TextInput as NativeTextInput, StyleSheet, TextInputProps, } from 'react-native'; -import { appTheme } from '../theme'; import { INPUT_HEIGHT } from '../constants'; +import { + Theme, + defaultTheme, + useTheme, +} from '@stream-io/video-react-native-sdk'; export const TextInput = ( props: Omit, ) => { + const styles = useStyles(); return ( { + let appTheme: Theme; + try { + /* eslint-disable react-hooks/rules-of-hooks */ + appTheme = useTheme()?.theme; + } catch (e) { + appTheme = defaultTheme; + } + return useMemo( + () => + StyleSheet.create({ + input: { + paddingLeft: appTheme.variants.spacingSizes.lg, + marginVertical: appTheme.variants.spacingSizes.md, + height: INPUT_HEIGHT, + backgroundColor: appTheme.colors.sheetSecondary, + borderRadius: 8, + borderColor: appTheme.colors.buttonPrimaryDisabled, + borderWidth: 1, + color: appTheme.colors.typePrimary, + fontSize: 17, + flex: 1, + }, + }), + [appTheme], + ); +}; diff --git a/sample-apps/react-native/dogfood/src/components/VideoEffectsButton/index.tsx b/sample-apps/react-native/dogfood/src/components/VideoEffectsButton/index.tsx index 05fddd8405..7456e16a93 100644 --- a/sample-apps/react-native/dogfood/src/components/VideoEffectsButton/index.tsx +++ b/sample-apps/react-native/dogfood/src/components/VideoEffectsButton/index.tsx @@ -5,7 +5,7 @@ import { BackgroundFiltersProvider, useTheme, } from '@stream-io/video-react-native-sdk'; -import React, { useState } from 'react'; +import React, { useMemo, useState } from 'react'; import { Image, Modal, @@ -45,6 +45,7 @@ const FilterButton = () => { const [modalVisible, setModalVisible] = useState(false); const closeModal = () => setModalVisible(false); const { theme } = useTheme(); + const styles = useStyles(); const { disableCustomFilter } = useCustomVideoFilters(); const { isSupported, disableAllFilters } = useBackgroundFilters(); @@ -95,6 +96,7 @@ const FilterButton = () => { }; const CustomFiltersRow = ({ closeModal }: { closeModal: () => void }) => { + const styles = useStyles(); const { applyGrayScaleFilter, currentCustomFilter } = useCustomVideoFilters(); const grayScaleSelected = currentCustomFilter === 'GrayScale'; return ( @@ -123,6 +125,7 @@ const ModalFilterButton = ({ onPress: () => void; closeModal: () => void; }) => { + const styles = useStyles(); return (