Skip to content

Commit

Permalink
✨(frontend) introduce a side panel for effects
Browse files Browse the repository at this point in the history
It simply render the video track if enabled. It's a basis
for building the 'blur your screen' feature.

More in the upcoming commits.
  • Loading branch information
lebaudantoine committed Sep 21, 2024
1 parent 6c2cace commit 9e35562
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 10 deletions.
68 changes: 68 additions & 0 deletions src/frontend/src/features/rooms/livekit/components/Effects.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { useEffect, useRef } from 'react'
import { useLocalParticipant } from '@livekit/components-react'
import { LocalVideoTrack } from 'livekit-client'
import { Div, P } from '@/primitives'
import { useTranslation } from 'react-i18next'

export const Effects = () => {
const { t } = useTranslation('rooms', { keyPrefix: 'effects' })
const { isCameraEnabled, cameraTrack } = useLocalParticipant()
const videoRef = useRef<HTMLVideoElement>(null)

const localCameraTrack = cameraTrack?.track as LocalVideoTrack

useEffect(() => {
const videoElement = videoRef.current

const attachVideoTrack = async () => {
if (!videoElement) return
localCameraTrack?.attach(videoElement)
}

attachVideoTrack()

return () => {
if (!videoElement) return
localCameraTrack.detach(videoElement)
}
}, [localCameraTrack, isCameraEnabled])

return (
<Div padding="0 1.5rem">
{localCameraTrack && isCameraEnabled ? (
<video
ref={videoRef}
width="100%"
muted
style={{
transform: 'rotateY(180deg)',
minHeight: '173px',
borderRadius: '4px',
}}
/>
) : (
<div
style={{
width: '100%',
height: '174px',
display: 'flex',
backgroundColor: 'black',
justifyContent: 'center',
flexDirection: 'column',
}}
>
<P
style={{
color: 'white',
textAlign: 'center',
textWrap: 'balance',
marginBottom: 0,
}}
>
{t('activateCamera')}
</P>
</div>
)}
</Div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { useTranslation } from 'react-i18next'
import { ParticipantsList } from './controls/Participants/ParticipantsList'
import { useWidgetInteraction } from '../hooks/useWidgetInteraction'
import { ReactNode } from 'react'
import { Effects } from './Effects'

type StyledSidePanelProps = {
title: string
Expand Down Expand Up @@ -65,7 +66,7 @@ export const SidePanel = () => {
const layoutSnap = useSnapshot(layoutStore)
const sidePanel = layoutSnap.sidePanel

const { isParticipantsOpen } = useWidgetInteraction()
const { isParticipantsOpen, isEffectsOpen } = useWidgetInteraction()
const { t } = useTranslation('rooms', { keyPrefix: 'sidePanel' })

if (!sidePanel) {
Expand All @@ -81,6 +82,7 @@ export const SidePanel = () => {
})}
>
{isParticipantsOpen && <ParticipantsList />}
{isEffectsOpen && <Effects />}
</StyledSidePanel>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { useTranslation } from 'react-i18next'
import { Dispatch, SetStateAction } from 'react'
import { DialogState } from './OptionsButton'
import { Separator } from '@/primitives/Separator'
import { useWidgetInteraction } from '../../../hooks/useWidgetInteraction'

// @todo try refactoring it to use MenuList component
export const OptionsMenuItems = ({
Expand All @@ -18,7 +19,7 @@ export const OptionsMenuItems = ({
onOpenDialog: Dispatch<SetStateAction<DialogState>>
}) => {
const { t } = useTranslation('rooms', { keyPrefix: 'options.items' })

const { toggleEffects } = useWidgetInteraction()
return (
<RACMenu
style={{
Expand All @@ -28,7 +29,7 @@ export const OptionsMenuItems = ({
>
<Section>
<MenuItem
onAction={() => console.log('open dialog')}
onAction={() => toggleEffects()}
className={menuItemRecipe({ icon: true })}
>
<RiAccountBoxLine size={20} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const useWidgetInteraction = () => {
const sidePanel = layoutSnap.sidePanel

const isParticipantsOpen = sidePanel == 'participants'
const isEffectsOpen = sidePanel == 'effects'

const toggleParticipants = () => {
if (dispatch && state?.showChat) {
Expand All @@ -26,11 +27,20 @@ export const useWidgetInteraction = () => {
}
}

const toggleEffects = () => {
if (dispatch && state?.showChat) {
dispatch({ msg: 'toggle_chat' })
}
layoutStore.sidePanel = isEffectsOpen ? null : 'effects'
}

return {
toggleParticipants,
toggleChat,
toggleEffects,
isChatOpen: state?.showChat,
unreadMessages: state?.unreadMessages,
isParticipantsOpen,
isEffectsOpen,
}
}
9 changes: 7 additions & 2 deletions src/frontend/src/locales/de/rooms.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,17 @@
"effects": ""
}
},
"effects": {
"activateCamera": ""
},
"sidePanel" : {
"heading": {
"participants": ""
"participants": "",
"effects": ""
},
"content": {
"participants": ""
"participants": "",
"effects": ""
},
"closeButton": ""
},
Expand Down
9 changes: 7 additions & 2 deletions src/frontend/src/locales/en/rooms.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,17 @@
"effects": "Apply effects"
}
},
"effects": {
"activateCamera": "Camera is disabled"
},
"sidePanel" : {
"heading": {
"participants": "Participants"
"participants": "Participants",
"effects": "Effects"
},
"content": {
"participants": "participants"
"participants": "participants",
"effects": "effects"
},
"closeButton": "Hide {{content}}"
},
Expand Down
9 changes: 7 additions & 2 deletions src/frontend/src/locales/fr/rooms.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,17 @@
"effects": "Appliquer des effets"
}
},
"effects": {
"activateCamera": "Votre camera est désactivée"
},
"sidePanel" : {
"heading": {
"participants": "Participants"
"participants": "Participants",
"effects": "Effets"
},
"content": {
"participants": "les participants"
"participants": "les participants",
"effects": "les effets"
},
"closeButton": "Masquer {{content}}"
},
Expand Down
2 changes: 1 addition & 1 deletion src/frontend/src/stores/layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { proxy } from 'valtio'

type State = {
showHeader: boolean
sidePanel: 'participants' | null
sidePanel: 'participants' | 'effects' | null
}

export const layoutStore = proxy<State>({
Expand Down

0 comments on commit 9e35562

Please sign in to comment.