Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit c319426

Browse files
committed
Add CallViewDropdownButton
Signed-off-by: Šimon Brandner <[email protected]>
1 parent bd7e822 commit c319426

File tree

1 file changed

+59
-10
lines changed

1 file changed

+59
-10
lines changed

src/components/views/voip/CallView/CallViewButtons.tsx

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
1616
limitations under the License.
1717
*/
1818

19-
import React, { createRef } from "react";
19+
import React, { createRef, useState } from "react";
2020
import classNames from "classnames";
2121
import AccessibleTooltipButton from "../../elements/AccessibleTooltipButton";
2222
import CallContextMenu from "../../context_menus/CallContextMenu";
@@ -28,8 +28,11 @@ import {
2828
alwaysAboveRightOf,
2929
ChevronFace,
3030
ContextMenuTooltipButton,
31+
useContextMenu,
3132
} from '../../../structures/ContextMenu';
3233
import { _t } from "../../../../languageHandler";
34+
import DeviceContextMenu from "../../context_menus/DeviceContextMenu";
35+
import { MediaDeviceKindEnum } from "../../../../MediaDeviceHandler";
3336

3437
// Height of the header duplicated from CSS because we need to subtract it from our max
3538
// height to get the max height of the video
@@ -39,15 +42,22 @@ const TOOLTIP_Y_OFFSET = -24;
3942

4043
const CONTROLS_HIDE_DELAY = 2000;
4144

42-
interface IButtonProps {
45+
interface IButtonProps extends Omit<React.ComponentProps<typeof AccessibleTooltipButton>, "title"> {
4346
state: boolean;
4447
className: string;
45-
onLabel: string;
46-
offLabel: string;
47-
onClick: () => void;
48+
onLabel?: string;
49+
offLabel?: string;
50+
onClick: (event: React.MouseEvent) => void;
4851
}
4952

50-
const CallViewToggleButton: React.FC<IButtonProps> = ({ state: isOn, className, onLabel, offLabel, onClick }) => {
53+
const CallViewToggleButton: React.FC<IButtonProps> = ({
54+
children,
55+
state: isOn,
56+
className,
57+
onLabel,
58+
offLabel,
59+
...props
60+
}) => {
5161
const classes = classNames("mx_CallViewButtons_button", className, {
5262
mx_CallViewButtons_button_on: isOn,
5363
mx_CallViewButtons_button_off: !isOn,
@@ -56,11 +66,48 @@ const CallViewToggleButton: React.FC<IButtonProps> = ({ state: isOn, className,
5666
return (
5767
<AccessibleTooltipButton
5868
className={classes}
59-
onClick={onClick}
6069
title={isOn ? onLabel : offLabel}
6170
alignment={Alignment.Top}
6271
yOffset={TOOLTIP_Y_OFFSET}
63-
/>
72+
{...props}
73+
>
74+
{ children }
75+
</AccessibleTooltipButton>
76+
);
77+
};
78+
79+
interface IDropdownButtonProps extends IButtonProps {
80+
deviceKinds: MediaDeviceKindEnum[];
81+
}
82+
83+
const CallViewDropdownButton: React.FC<IDropdownButtonProps> = ({ state, deviceKinds, ...props }) => {
84+
const [menuDisplayed, buttonRef, openMenu, closeMenu] = useContextMenu();
85+
const [hoveringDropdown, setHoveringDropdown] = useState(false);
86+
87+
const classes = classNames("mx_CallViewButtons_button", "mx_CallViewButtons_dropdownButton", {
88+
mx_CallViewButtons_dropdownButton_collapsed: !menuDisplayed,
89+
});
90+
91+
const onClick = (event: React.MouseEvent): void => {
92+
event.stopPropagation();
93+
openMenu();
94+
};
95+
96+
return (
97+
<CallViewToggleButton inputRef={buttonRef} forceHide={menuDisplayed || hoveringDropdown} state={state} {...props}>
98+
<CallViewToggleButton
99+
className={classes}
100+
onClick={onClick}
101+
onHover={(hovering) => setHoveringDropdown(hovering)}
102+
state={state}
103+
/>
104+
{ menuDisplayed && <DeviceContextMenu
105+
{...alwaysAboveRightOf(buttonRef.current?.getBoundingClientRect())}
106+
107+
onFinished={closeMenu}
108+
deviceKinds={deviceKinds}
109+
/> }
110+
</CallViewToggleButton>
64111
);
65112
};
66113

@@ -221,19 +268,21 @@ export default class CallViewButtons extends React.Component<IProps, IState> {
221268
alignment={Alignment.Top}
222269
yOffset={TOOLTIP_Y_OFFSET}
223270
/> }
224-
<CallViewToggleButton
271+
<CallViewDropdownButton
225272
state={!this.props.buttonsState.micMuted}
226273
className="mx_CallViewButtons_button_mic"
227274
onLabel={_t("Mute the microphone")}
228275
offLabel={_t("Unmute the microphone")}
229276
onClick={this.props.handlers.onMicMuteClick}
277+
deviceKinds={[MediaDeviceKindEnum.AudioInput, MediaDeviceKindEnum.AudioOutput]}
230278
/>
231-
{ this.props.buttonsVisibility.vidMute && <CallViewToggleButton
279+
{ this.props.buttonsVisibility.vidMute && <CallViewDropdownButton
232280
state={!this.props.buttonsState.vidMuted}
233281
className="mx_CallViewButtons_button_vid"
234282
onLabel={_t("Stop the camera")}
235283
offLabel={_t("Start the camera")}
236284
onClick={this.props.handlers.onVidMuteClick}
285+
deviceKinds={[MediaDeviceKindEnum.VideoInput]}
237286
/> }
238287
{ this.props.buttonsVisibility.screensharing && <CallViewToggleButton
239288
state={this.props.buttonsState.screensharing}

0 commit comments

Comments
 (0)