/* Copyright 2022-2024 New Vector Ltd. Copyright 2026 Element Creations Ltd. SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE in the repository root for full details. */ import { type ComponentPropsWithoutRef, type FC } from "react"; import classNames from "classnames"; import { useTranslation } from "react-i18next"; import { Button as CpdButton, IconButton, Tooltip, } from "@vector-im/compound-web"; import { MicOnSolidIcon, MicOffSolidIcon, VideoCallSolidIcon, VideoCallOffSolidIcon, EndCallIcon, ShareScreenSolidIcon, OverflowHorizontalIcon, OverflowVerticalIcon, VolumeOnSolidIcon, } from "@vector-im/compound-design-tokens/assets/web/icons"; import styles from "./Button.module.css"; import callFooterStyles from "../components/CallFooter.module.css"; import { platform } from "../Platform"; interface MicButtonProps extends ComponentPropsWithoutRef<"button"> { enabled: boolean; size?: "sm" | "lg"; } export const MicButton: FC = ({ enabled, ...props }) => { const { t } = useTranslation(); const Icon = enabled ? MicOnSolidIcon : MicOffSolidIcon; const label = enabled ? t("mute_microphone_button_label") : t("unmute_microphone_button_label"); return ( ); }; interface VideoButtonProps extends ComponentPropsWithoutRef<"button"> { enabled: boolean; size?: "sm" | "lg"; } export const VideoButton: FC = ({ enabled, ...props }) => { const { t } = useTranslation(); const Icon = enabled ? VideoCallSolidIcon : VideoCallOffSolidIcon; const label = enabled ? t("stop_video_button_label") : t("start_video_button_label"); return ( ); }; interface ShareScreenButtonProps extends ComponentPropsWithoutRef<"button"> { enabled: boolean; size: "sm" | "lg"; } export const ShareScreenButton: FC = ({ enabled, ...props }) => { const { t } = useTranslation(); const label = enabled ? t("stop_screenshare_button_label") : t("screenshare_button_label"); return ( ); }; interface EndCallButtonProps extends ComponentPropsWithoutRef<"button"> { size?: "sm" | "lg"; } export const EndCallButton: FC = ({ className, ...props }) => { const { t } = useTranslation(); return ( ); }; interface LoudspeakerButtonProps extends ComponentPropsWithoutRef<"button"> { size?: "sm" | "lg"; /** The button will be rendered: * true: currently in loudspeaker mode, pressing will switch to earpiece (rendered as enabled) * false: currently in earpiece mode, pressing will switch to loudspeaker (rendered as disabled) */ isEarpieceTarget: boolean; } export const LoudspeakerButton: FC = (props) => { const { t } = useTranslation(); const label = props.isEarpieceTarget ? t("settings.devices.handset") : t("settings.devices.loudspeaker"); // if the target is the earpice, we are currently in loudspeaker mode. const enabled = props.isEarpieceTarget; return ( ); }; function classNamesForScrrenWidth( className?: string, forScreenWidth?: "wide" | "narrow", ): string { return classNames(className, { [callFooterStyles.settingsOnlyShowWide]: forScreenWidth === "wide", [callFooterStyles.settingsOnlyShowNarrow]: forScreenWidth === "narrow", }); } interface SettingsIconButtonProps extends ComponentPropsWithoutRef<"button"> { /** If this buttons should be setup to be used in the app bar */ showForScreenWidth?: "wide" | "narrow"; kind?: "secondary" | "primary"; } export const SettingsIconButton: FC = ({ showForScreenWidth, className, ...props }) => { const { t } = useTranslation(); const Icon = platform === "android" ? OverflowVerticalIcon : OverflowHorizontalIcon; return ( ); }; interface SettingsButtonProps extends ComponentPropsWithoutRef<"button"> { size?: "sm" | "lg"; /** If this buttons should be setup to be used in the app bar */ showForScreenWidth?: "wide" | "narrow"; } export const SettingsButton: FC = ({ showForScreenWidth, className, ...props }) => { const { t } = useTranslation(); return ( ); };