11// Copyright (c) Microsoft Corporation.
22// Licensed under the MIT License.
33
4- import { concatStyleSets , Icon } from '@fluentui/react' ;
4+ import { concatStyleSets , Icon , IStyle , PartialTheme } from '@fluentui/react' ;
5+ /* @conditional -compile-remove(end-call-options) */
6+ import { IContextualMenuProps } from '@fluentui/react' ;
57import React from 'react' ;
68import { useLocale } from '../localization' ;
79import { useTheme } from '../theming' ;
8- import { darkTheme , lightTheme } from '../theming/themes' ;
10+ import { CallingTheme , darkTheme , lightTheme } from '../theming/themes' ;
911import { isDarkThemed } from '../theming/themeUtils' ;
1012import { ControlBarButton , ControlBarButtonProps } from './ControlBarButton' ;
13+ /* @conditional -compile-remove(end-call-options) */
14+ import { _preventDismissOnEvent as preventDismissOnEvent } from '@internal/acs-ui-common' ;
1115
1216/**
1317 * Strings of {@link EndCallButton} that can be overridden.
@@ -21,6 +25,14 @@ export interface EndCallButtonStrings {
2125 label : string ;
2226 /** Tooltip content. */
2327 tooltipContent ?: string ;
28+
29+ /* @conditional -compile-remove(end-call-options) */
30+ /** Label for leave option when ending call */
31+ leaveOption ?: string ;
32+
33+ /* @conditional -compile-remove(end-call-options) */
34+ /** Label for end the whole call option when ending call */
35+ endCallOption ?: string ;
2436}
2537
2638/**
@@ -33,7 +45,14 @@ export interface EndCallButtonProps extends ControlBarButtonProps {
3345 * Utility property for using this component with `communication react eventHandlers`.
3446 * Maps directly to the `onClick` property.
3547 */
36- onHangUp ?: ( ) => Promise < void > ;
48+ onHangUp ?: ( forEveryone ?: boolean ) => Promise < void > ;
49+
50+ /* @conditional -compile-remove(end-call-options) */
51+ /**
52+ * Set this to true to make it a split button.
53+ * The split arrow will trigger a contextual menu to allow end for everyone or just for the user.
54+ */
55+ enableEndCallMenu ?: boolean ;
3756
3857 /**
3958 * Optional strings to override in component
@@ -51,7 +70,7 @@ const onRenderEndCallIcon = (): JSX.Element => <Icon iconName="ControlButtonEndC
5170 * @public
5271 */
5372export const EndCallButton = ( props : EndCallButtonProps ) : JSX . Element => {
54- const { styles } = props ;
73+ const { styles, /* @conditional -compile-remove(end-call-options) */ enableEndCallMenu , onHangUp } = props ;
5574
5675 const localeStrings = useLocale ( ) . strings . endCallButton ;
5776 const strings = { ...localeStrings , ...props . strings } ;
@@ -63,71 +82,128 @@ export const EndCallButton = (props: EndCallButtonProps): JSX.Element => {
6382 styles ?? { }
6483 ) ;
6584
85+ /* @conditional -compile-remove(end-call-options) */
86+ const defaultMenuProps : IContextualMenuProps = {
87+ items : [
88+ {
89+ key : 'endForSelf' ,
90+ text : localeStrings . leaveOption ,
91+ title : localeStrings . leaveOption ,
92+ onClick : ( ) => {
93+ onHangUp && onHangUp ( false ) ;
94+ }
95+ } ,
96+ {
97+ key : 'endForEveryone' ,
98+ text : localeStrings . endCallOption ,
99+ title : localeStrings . endCallOption ,
100+ onClick : ( ) => {
101+ onHangUp && onHangUp ( true ) ;
102+ }
103+ }
104+ ] ,
105+ styles : props . styles ,
106+ calloutProps : {
107+ styles : {
108+ root : {
109+ maxWidth : '95%'
110+ }
111+ } ,
112+ preventDismissOnEvent
113+ }
114+ } ;
115+
66116 return (
67- < ControlBarButton
68- { ...props }
69- onClick = { props . onHangUp ?? props . onClick }
70- styles = { componentStyles }
71- onRenderIcon = { props . onRenderIcon ?? onRenderEndCallIcon }
72- strings = { strings }
73- labelKey = { props . labelKey ?? 'endCallButtonLabel' }
74- />
117+ < >
118+ < ControlBarButton
119+ { ...props }
120+ /* @conditional -compile-remove(end-call-options) */
121+ menuProps = { enableEndCallMenu ? defaultMenuProps : undefined }
122+ onClick = { onHangUp ? ( ) => onHangUp ( ) : props . onClick }
123+ styles = { componentStyles }
124+ onRenderIcon = { props . onRenderIcon ?? onRenderEndCallIcon }
125+ strings = { strings }
126+ labelKey = { props . labelKey ?? 'endCallButtonLabel' }
127+ />
128+ </ >
75129 ) ;
76130} ;
77- // using media query to prevent windows from overwriting the button color
78- const darkThemeCallButtonStyles = {
79- root : {
80- color : darkTheme . callingPalette . iconWhite ,
81- background : darkTheme . callingPalette . callRed ,
131+
132+ const getButtonStyles = (
133+ theme : PartialTheme & CallingTheme
134+ ) : { regular : IStyle ; pressed : IStyle ; hovered : IStyle } => ( {
135+ regular : {
136+ color : theme . callingPalette . iconWhite ,
137+ background : theme . callingPalette . callRed ,
82138 '@media (forced-colors: active)' : {
83139 forcedColorAdjust : 'auto' ,
84- border : `1px ${ lightTheme . palette ?. neutralQuaternaryAlt } solid`
140+ border : `1px ${ theme . palette ?. neutralQuaternaryAlt } solid`
141+ } ,
142+ ' i' : {
143+ color : theme . callingPalette . iconWhite
85144 } ,
86- ':focus::after' : { outlineColor : `${ darkTheme . callingPalette . iconWhite } !important` } // added !important to avoid override by FluentUI button styles
145+ ':focus::after' : { outlineColor : `${ theme . callingPalette . iconWhite } !important` } // added !important to avoid override by FluentUI button styles
87146 } ,
88- rootHovered : {
89- color : darkTheme . callingPalette . iconWhite ,
90- background : darkTheme . callingPalette . callRed ,
147+ pressed : {
148+ color : theme . callingPalette . iconWhite ,
149+ background : theme . callingPalette . callRedDarker ,
150+ border : 'none' ,
151+ ' i' : {
152+ color : theme . callingPalette . iconWhite
153+ } ,
91154 '@media (forced-colors: active)' : {
92155 forcedColorAdjust : 'auto'
93156 }
94157 } ,
95- rootPressed : {
96- color : darkTheme . callingPalette . iconWhite ,
97- background : darkTheme . callingPalette . callRed ,
158+ hovered : {
159+ color : theme . callingPalette . iconWhite ,
160+ background : theme . callingPalette . callRedDark ,
161+ border : 'none' ,
162+ ' i' : {
163+ color : theme . callingPalette . iconWhite
164+ } ,
98165 '@media (forced-colors: active)' : {
99166 forcedColorAdjust : 'auto'
100167 }
101- } ,
168+ }
169+ } ) ;
170+
171+ const darkThemeButtonStyles = getButtonStyles ( darkTheme ) ;
172+ const lightThemeButtonStyles = getButtonStyles ( lightTheme ) ;
173+
174+ // using media query to prevent windows from overwriting the button color
175+ const darkThemeCallButtonStyles = {
176+ root : darkThemeButtonStyles . regular ,
177+ rootHovered : darkThemeButtonStyles . hovered ,
178+ rootPressed : darkThemeButtonStyles . pressed ,
102179 label : {
103180 color : darkTheme . callingPalette . iconWhite
104- }
181+ } ,
182+ splitButtonMenuButton : {
183+ ...( darkThemeButtonStyles . regular as object ) ,
184+ borderTop : 'none' ,
185+ borderRight : 'none' ,
186+ borderBottom : 'none' ,
187+ '&:hover' : darkThemeButtonStyles . hovered
188+ } ,
189+ splitButtonMenuButtonChecked : darkThemeButtonStyles . hovered ,
190+ splitButtonMenuButtonExpanded : darkThemeButtonStyles . pressed
105191} ;
106192
107193const lightThemeCallButtonStyles = {
108- root : {
109- color : lightTheme . callingPalette . iconWhite ,
110- background : lightTheme . callingPalette . callRed ,
111- '@media (forced-colors: active)' : {
112- forcedColorAdjust : 'auto' ,
113- border : `1px ${ lightTheme . palette ?. neutralQuaternaryAlt } solid`
114- } ,
115- ':focus::after' : { outlineColor : `${ lightTheme . callingPalette . iconWhite } !important` } // added !important to avoid override by FluentUI button styles
116- } ,
117- rootHovered : {
118- color : lightTheme . callingPalette . iconWhite ,
119- background : lightTheme . callingPalette . callRed ,
120- '@media (forced-colors: active)' : {
121- forcedColorAdjust : 'auto'
122- }
123- } ,
124- rootPressed : {
125- color : lightTheme . callingPalette . iconWhite ,
126- background : lightTheme . callingPalette . callRed ,
127- '@media (forced-colors: active)' : {
128- forcedColorAdjust : 'auto'
129- }
194+ root : lightThemeButtonStyles . regular ,
195+ rootHovered : lightThemeButtonStyles . hovered ,
196+ rootPressed : lightThemeButtonStyles . pressed ,
197+ splitButtonMenuButton : {
198+ ...( lightThemeButtonStyles . regular as object ) ,
199+ borderTop : 'none' ,
200+ borderRight : 'none' ,
201+ borderBottom : 'none' ,
202+ '&:hover' : lightThemeButtonStyles . hovered
130203 } ,
204+ splitButtonMenuButtonChecked : lightThemeButtonStyles . hovered ,
205+ splitButtonMenuButtonExpanded : lightThemeButtonStyles . pressed ,
206+ splitButtonMenuFocused : lightThemeButtonStyles . pressed ,
131207 label : {
132208 color : lightTheme . callingPalette . iconWhite
133209 }
0 commit comments