From 4b7419fe4a38a45b8bb7bf027dcbfa93b5567e7f Mon Sep 17 00:00:00 2001 From: lebaudantoine Date: Wed, 28 Aug 2024 15:11:56 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8(frontend)=20create=20a=20reusable=20a?= =?UTF-8?q?ctive=20speaker=20component?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit oupsy, heavily copied from Gmeet. Thx Nathan Vasse for his css animation skills, he crushed it. This component will be core in the app, and reused in many places. It was necessary for the participants list. --- src/frontend/panda.config.ts | 12 ++++ .../rooms/components/ActiveSpeaker.tsx | 70 +++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 src/frontend/src/features/rooms/components/ActiveSpeaker.tsx diff --git a/src/frontend/panda.config.ts b/src/frontend/panda.config.ts index 99a4d1e8..088017dc 100644 --- a/src/frontend/panda.config.ts +++ b/src/frontend/panda.config.ts @@ -63,6 +63,18 @@ const config: Config = { '75%': { boxShadow: '0 0 0 30px rgba(255, 255, 255, 0)' }, '100%': { boxShadow: '0 0 0 0 rgba(255, 255, 255, 0)' }, }, + active_speaker: { + '0%': { height: '4px' }, + '25%': { height: '8px' }, + '50%': { height: '6px' }, + '100%': { height: '16px' }, + }, + active_speake_small: { + '0%': { height: '4px' }, + '25%': { height: '6px' }, + '50%': { height: '4px' }, + '100%': { height: '8px' }, + }, }, tokens: defineTokens({ /* we take a few things from the panda preset but for now we clear out some stuff. diff --git a/src/frontend/src/features/rooms/components/ActiveSpeaker.tsx b/src/frontend/src/features/rooms/components/ActiveSpeaker.tsx new file mode 100644 index 00000000..cf489d6d --- /dev/null +++ b/src/frontend/src/features/rooms/components/ActiveSpeaker.tsx @@ -0,0 +1,70 @@ +import { styled } from '@/styled-system/jsx' + +const StyledContainer = styled('div', { + base: { + width: '24px', + height: '24px', + boxSizing: 'border-box', + backgroundColor: 'primary', + borderRadius: '100%', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + gap: '2px', + }, +}) + +const StyledChild = styled('div', { + base: { + backgroundColor: 'white', + width: '4px', + height: '4px', + borderRadius: '4px', + animationDuration: '400ms', + animationName: 'active_speaker', + animationIterationCount: 'infinite', + animationDirection: 'alternate', + }, + variants: { + active: { + true: { + animationIterationCount: 'infinite', + }, + false: { + animationIterationCount: 0, + }, + }, + size: { + small: { + animationName: 'active_speake_small', + }, + }, + }, +}) + +export const ActiveSpeaker = ({ isSpeaking }: { isSpeaking: boolean }) => { + return ( + + + + + + ) +}