diff --git a/src/index.css b/src/index.css index 25562e3..0272651 100644 --- a/src/index.css +++ b/src/index.css @@ -26,6 +26,8 @@ limitations under the License. --inter-unicode-range: U+0000-20e2, U+20e4-23ce, U+23d0-24c1, U+24c3-259f, U+25c2-2664, U+2666-2763, U+2765-2b05, U+2b07-2b1b, U+2b1d-10FFFF; --primaryColor: #0dbd8b; + --primaryColor-20: #0dbd8b33; + --alert-20: #ff5b5533; --bgColor1: #15191e; --bgColor2: #21262c; --bgColor3: #444; diff --git a/src/room/PTTButton.module.css b/src/room/PTTButton.module.css index d6b7a76..fb849ad 100644 --- a/src/room/PTTButton.module.css +++ b/src/room/PTTButton.module.css @@ -14,14 +14,10 @@ .talking { background-color: #0dbd8b; - box-shadow: 0px 0px 0px 17px rgba(13, 189, 139, 0.2), - 0px 0px 0px 34px rgba(13, 189, 139, 0.2); cursor: unset; } .error { background-color: #ff5b55; border-color: #ff5b55; - box-shadow: 0px 0px 0px 17px rgba(255, 91, 85, 0.2), - 0px 0px 0px 34px rgba(255, 91, 85, 0.2); } diff --git a/src/room/PTTButton.tsx b/src/room/PTTButton.tsx index 4da324c..62299a1 100644 --- a/src/room/PTTButton.tsx +++ b/src/room/PTTButton.tsx @@ -16,6 +16,7 @@ limitations under the License. import React, { useCallback, useEffect, useState, createRef } from "react"; import classNames from "classnames"; +import { useSpring, animated } from "@react-spring/web"; import styles from "./PTTButton.module.css"; import { ReactComponent as MicIcon } from "../icons/Mic.svg"; @@ -27,6 +28,7 @@ interface Props { activeSpeakerDisplayName: string; activeSpeakerAvatarUrl: string; activeSpeakerIsLocalUser: boolean; + activeSpeakerVolume: number; size: number; startTalking: () => void; stopTalking: () => void; @@ -44,6 +46,7 @@ export const PTTButton: React.FC = ({ activeSpeakerDisplayName, activeSpeakerAvatarUrl, activeSpeakerIsLocalUser, + activeSpeakerVolume, size, startTalking, stopTalking, @@ -130,12 +133,32 @@ export const PTTButton: React.FC = ({ ); }; }, [onWindowMouseUp, onWindowTouchEnd, onButtonTouchStart, buttonRef]); + + const { shadow } = useSpring({ + shadow: (Math.max(activeSpeakerVolume, -70) + 70) * 0.6, + config: { + clamp: true, + tension: 300, + }, + }); + const shadowColor = showTalkOverError + ? "var(--alert-20)" + : "var(--primaryColor-20)"; + return ( - + ); }; diff --git a/src/room/PTTCallView.tsx b/src/room/PTTCallView.tsx index e4aadf1..5e3f304 100644 --- a/src/room/PTTCallView.tsx +++ b/src/room/PTTCallView.tsx @@ -123,6 +123,7 @@ export const PTTCallView: React.FC = ({ talkOverEnabled, setTalkOverEnabled, activeSpeakerUserId, + activeSpeakerVolume, startTalking, stopTalking, transmitBlocked, @@ -221,6 +222,7 @@ export const PTTCallView: React.FC = ({ activeSpeakerDisplayName={activeSpeakerDisplayName} activeSpeakerAvatarUrl={activeSpeakerAvatarUrl} activeSpeakerIsLocalUser={activeSpeakerIsLocalUser} + activeSpeakerVolume={activeSpeakerVolume} size={pttButtonSize} startTalking={startTalking} stopTalking={stopTalking} diff --git a/src/room/usePTT.ts b/src/room/usePTT.ts index e677e9a..7710655 100644 --- a/src/room/usePTT.ts +++ b/src/room/usePTT.ts @@ -65,6 +65,7 @@ export interface PTTState { talkOverEnabled: boolean; setTalkOverEnabled: (boolean) => void; activeSpeakerUserId: string; + activeSpeakerVolume: number; startTalking: () => void; stopTalking: () => void; transmitBlocked: boolean; @@ -108,6 +109,7 @@ export const usePTT = ( isAdmin, talkOverEnabled, activeSpeakerUserId, + activeSpeakerVolume, transmitBlocked, }, setState, @@ -121,6 +123,7 @@ export const usePTT = ( talkOverEnabled: false, pttButtonHeld: false, activeSpeakerUserId: activeSpeakerFeed ? activeSpeakerFeed.userId : null, + activeSpeakerVolume: -Infinity, transmitBlocked: false, }; }); @@ -152,15 +155,11 @@ export const usePTT = ( playClip(PTTClipID.BLOCKED); } - setState((prevState) => { - return { - ...prevState, - activeSpeakerUserId: activeSpeakerFeed - ? activeSpeakerFeed.userId - : null, - transmitBlocked: blocked, - }; - }); + setState((prevState) => ({ + ...prevState, + activeSpeakerUserId: activeSpeakerFeed ? activeSpeakerFeed.userId : null, + transmitBlocked: blocked, + })); }, [ playClip, groupCall, @@ -173,7 +172,7 @@ export const usePTT = ( useEffect(() => { for (const callFeed of userMediaFeeds) { - callFeed.addListener(CallFeedEvent.MuteStateChanged, onMuteStateChanged); + callFeed.on(CallFeedEvent.MuteStateChanged, onMuteStateChanged); } const activeSpeakerFeed = getActiveSpeakerFeed(userMediaFeeds, groupCall); @@ -185,14 +184,30 @@ export const usePTT = ( return () => { for (const callFeed of userMediaFeeds) { - callFeed.removeListener( - CallFeedEvent.MuteStateChanged, - onMuteStateChanged - ); + callFeed.off(CallFeedEvent.MuteStateChanged, onMuteStateChanged); } }; }, [userMediaFeeds, onMuteStateChanged, groupCall]); + const onVolumeChanged = useCallback((volume: number) => { + setState((prevState) => ({ + ...prevState, + activeSpeakerVolume: volume, + })); + }, []); + + useEffect(() => { + const activeSpeakerFeed = getActiveSpeakerFeed(userMediaFeeds, groupCall); + activeSpeakerFeed?.on(CallFeedEvent.VolumeChanged, onVolumeChanged); + return () => { + activeSpeakerFeed?.off(CallFeedEvent.VolumeChanged, onVolumeChanged); + setState((prevState) => ({ + ...prevState, + activeSpeakerVolume: -Infinity, + })); + }; + }, [activeSpeakerUserId, onVolumeChanged, userMediaFeeds, groupCall]); + const startTalking = useCallback(async () => { if (pttButtonHeld) return; @@ -317,6 +332,7 @@ export const usePTT = ( talkOverEnabled, setTalkOverEnabled, activeSpeakerUserId, + activeSpeakerVolume, startTalking, stopTalking, transmitBlocked,