From 2a69b72bedc8804008b29966b35c37113c986e37 Mon Sep 17 00:00:00 2001 From: Robin Townsend Date: Tue, 31 May 2022 18:01:34 -0400 Subject: [PATCH 1/4] Add a VU meter-style animation to radio mode --- src/room/PTTButton.module.css | 4 ---- src/room/PTTButton.tsx | 27 +++++++++++++++++++-- src/room/PTTCallView.tsx | 2 ++ src/room/usePTT.ts | 44 ++++++++++++++++++++++++----------- 4 files changed, 57 insertions(+), 20 deletions(-) diff --git a/src/room/PTTButton.module.css b/src/room/PTTButton.module.css index 1a8dd17..73ca76d 100644 --- a/src/room/PTTButton.module.css +++ b/src/room/PTTButton.module.css @@ -13,13 +13,9 @@ .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); } .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..07db646 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.7, + config: { + clamp: true, + tension: 300, + }, + }); + const shadowColor = showTalkOverError + ? "rgba(255, 91, 85, 0.2)" + : "rgba(13, 189, 139, 0.2)"; + return ( - + ); }; diff --git a/src/room/PTTCallView.tsx b/src/room/PTTCallView.tsx index 4b395f8..5f46d8e 100644 --- a/src/room/PTTCallView.tsx +++ b/src/room/PTTCallView.tsx @@ -124,6 +124,7 @@ export const PTTCallView: React.FC = ({ talkOverEnabled, setTalkOverEnabled, activeSpeakerUserId, + activeSpeakerVolume, startTalking, stopTalking, transmitBlocked, @@ -223,6 +224,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 5965c54..02558f9 100644 --- a/src/room/usePTT.ts +++ b/src/room/usePTT.ts @@ -49,6 +49,7 @@ export interface PTTState { talkOverEnabled: boolean; setTalkOverEnabled: (boolean) => void; activeSpeakerUserId: string; + activeSpeakerVolume: number; startTalking: () => void; stopTalking: () => void; transmitBlocked: boolean; @@ -87,6 +88,7 @@ export const usePTT = ( isAdmin, talkOverEnabled, activeSpeakerUserId, + activeSpeakerVolume, transmitBlocked, }, setState, @@ -100,6 +102,7 @@ export const usePTT = ( talkOverEnabled: false, pttButtonHeld: false, activeSpeakerUserId: activeSpeakerFeed ? activeSpeakerFeed.userId : null, + activeSpeakerVolume: -Infinity, transmitBlocked: false, }; }); @@ -131,15 +134,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, @@ -152,7 +151,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); @@ -164,14 +163,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; @@ -275,6 +290,7 @@ export const usePTT = ( talkOverEnabled, setTalkOverEnabled, activeSpeakerUserId, + activeSpeakerVolume, startTalking, stopTalking, transmitBlocked, From 641e6c53b6b178a01da8fbc80880edc78b758d02 Mon Sep 17 00:00:00 2001 From: Robin Townsend Date: Tue, 31 May 2022 23:41:05 -0400 Subject: [PATCH 2/4] Make the animation smaller --- src/room/PTTButton.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/room/PTTButton.tsx b/src/room/PTTButton.tsx index 07db646..e2eb2fe 100644 --- a/src/room/PTTButton.tsx +++ b/src/room/PTTButton.tsx @@ -135,7 +135,7 @@ export const PTTButton: React.FC = ({ }, [onWindowMouseUp, onWindowTouchEnd, onButtonTouchStart, buttonRef]); const { shadow } = useSpring({ - shadow: (Math.max(activeSpeakerVolume, -70) + 70) * 0.7, + shadow: (Math.max(activeSpeakerVolume, -70) + 70) * 0.5, config: { clamp: true, tension: 300, From 25bde3560b89efd0ce4dacc662a68c6c826033e2 Mon Sep 17 00:00:00 2001 From: Robin Townsend Date: Wed, 1 Jun 2022 10:41:12 -0400 Subject: [PATCH 3/4] Use color variables --- src/index.css | 2 ++ src/room/PTTButton.tsx | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) 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.tsx b/src/room/PTTButton.tsx index e2eb2fe..62d5d37 100644 --- a/src/room/PTTButton.tsx +++ b/src/room/PTTButton.tsx @@ -142,8 +142,8 @@ export const PTTButton: React.FC = ({ }, }); const shadowColor = showTalkOverError - ? "rgba(255, 91, 85, 0.2)" - : "rgba(13, 189, 139, 0.2)"; + ? "var(--alert-20)" + : "var(--primaryColor-20)"; return ( Date: Wed, 1 Jun 2022 10:41:49 -0400 Subject: [PATCH 4/4] Bump the animation size up a little bit more --- src/room/PTTButton.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/room/PTTButton.tsx b/src/room/PTTButton.tsx index 62d5d37..62299a1 100644 --- a/src/room/PTTButton.tsx +++ b/src/room/PTTButton.tsx @@ -135,7 +135,7 @@ export const PTTButton: React.FC = ({ }, [onWindowMouseUp, onWindowTouchEnd, onButtonTouchStart, buttonRef]); const { shadow } = useSpring({ - shadow: (Math.max(activeSpeakerVolume, -70) + 70) * 0.5, + shadow: (Math.max(activeSpeakerVolume, -70) + 70) * 0.6, config: { clamp: true, tension: 300,