♻️(frontend) extract effects-related logic in a component
Wraps all logics related to the effects on prejoin screen in a dedicated component.
This commit is contained in:
committed by
aleb_the_flash
parent
3bd9363879
commit
12e2149b9e
@@ -13,12 +13,77 @@ import { Button, Dialog } from '@/primitives'
|
|||||||
import { LocalUserChoices } from '../routes/Room'
|
import { LocalUserChoices } from '../routes/Room'
|
||||||
import { Heading } from 'react-aria-components'
|
import { Heading } from 'react-aria-components'
|
||||||
import { RiImageCircleAiFill } from '@remixicon/react'
|
import { RiImageCircleAiFill } from '@remixicon/react'
|
||||||
import { EffectsConfiguration } from '../livekit/components/effects/EffectsConfiguration'
|
import {
|
||||||
|
EffectsConfiguration,
|
||||||
|
EffectsConfigurationProps,
|
||||||
|
} from '../livekit/components/effects/EffectsConfiguration'
|
||||||
import { usePersistentUserChoices } from '../livekit/hooks/usePersistentUserChoices'
|
import { usePersistentUserChoices } from '../livekit/hooks/usePersistentUserChoices'
|
||||||
import { BackgroundBlurFactory } from '../livekit/components/blur'
|
import { BackgroundBlurFactory } from '../livekit/components/blur'
|
||||||
|
|
||||||
const onError = (e: Error) => console.error('ERROR', e)
|
const onError = (e: Error) => console.error('ERROR', e)
|
||||||
|
|
||||||
|
const Effects = ({
|
||||||
|
videoTrack,
|
||||||
|
onSubmit,
|
||||||
|
}: Pick<EffectsConfigurationProps, 'videoTrack' | 'onSubmit'>) => {
|
||||||
|
const { t } = useTranslation('rooms', { keyPrefix: 'join.effects' })
|
||||||
|
const [isDialogOpen, setIsDialogOpen] = useState(false)
|
||||||
|
const openDialog = () => setIsDialogOpen(true)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Dialog
|
||||||
|
isOpen={isDialogOpen}
|
||||||
|
onOpenChange={setIsDialogOpen}
|
||||||
|
role="dialog"
|
||||||
|
type="flex"
|
||||||
|
size="large"
|
||||||
|
>
|
||||||
|
<Heading
|
||||||
|
slot="title"
|
||||||
|
level={1}
|
||||||
|
className={css({
|
||||||
|
textStyle: 'h1',
|
||||||
|
marginBottom: '1.5rem',
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
{t('title')}
|
||||||
|
</Heading>
|
||||||
|
<EffectsConfiguration videoTrack={videoTrack} onSubmit={onSubmit} />
|
||||||
|
</Dialog>
|
||||||
|
<div
|
||||||
|
className={css({
|
||||||
|
position: 'absolute',
|
||||||
|
right: 0,
|
||||||
|
bottom: '0',
|
||||||
|
padding: '1rem',
|
||||||
|
zIndex: '1',
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
variant="whiteCircle"
|
||||||
|
onPress={openDialog}
|
||||||
|
tooltip={t('description')}
|
||||||
|
aria-label={t('description')}
|
||||||
|
>
|
||||||
|
<RiImageCircleAiFill size={24} />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={css({
|
||||||
|
position: 'absolute',
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
|
height: '20%',
|
||||||
|
backgroundImage:
|
||||||
|
'linear-gradient(0deg, rgba(0,0,0,0.8) 0%, rgba(255,255,255,0) 100%)',
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export const Join = ({
|
export const Join = ({
|
||||||
onSubmit,
|
onSubmit,
|
||||||
}: {
|
}: {
|
||||||
@@ -123,12 +188,6 @@ export const Join = ({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const [isEffectsOpen, setEffectsOpen] = useState(false)
|
|
||||||
|
|
||||||
const openEffects = () => {
|
|
||||||
setEffectsOpen(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// This hook is used to setup the persisted user choice processor on initialization.
|
// This hook is used to setup the persisted user choice processor on initialization.
|
||||||
// So it's on purpose that processor is not included in the deps.
|
// So it's on purpose that processor is not included in the deps.
|
||||||
// We just want to wait for the videoTrack to be loaded to apply the default processor.
|
// We just want to wait for the videoTrack to be loaded to apply the default processor.
|
||||||
@@ -141,30 +200,6 @@ export const Join = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Screen footer={false}>
|
<Screen footer={false}>
|
||||||
<Dialog
|
|
||||||
isOpen={isEffectsOpen}
|
|
||||||
onOpenChange={setEffectsOpen}
|
|
||||||
role="dialog"
|
|
||||||
type="flex"
|
|
||||||
size="large"
|
|
||||||
>
|
|
||||||
<Heading
|
|
||||||
slot="title"
|
|
||||||
level={1}
|
|
||||||
className={css({
|
|
||||||
textStyle: 'h1',
|
|
||||||
marginBottom: '1.5rem',
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
{t('effects.title')}
|
|
||||||
</Heading>
|
|
||||||
<EffectsConfiguration
|
|
||||||
videoTrack={videoTrack}
|
|
||||||
onSubmit={(processor) => {
|
|
||||||
setProcessor(processor)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Dialog>
|
|
||||||
<div
|
<div
|
||||||
className={css({
|
className={css({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
@@ -257,34 +292,7 @@ export const Join = ({
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div
|
<Effects videoTrack={videoTrack} onSubmit={setProcessor} />
|
||||||
className={css({
|
|
||||||
position: 'absolute',
|
|
||||||
left: 0,
|
|
||||||
right: 0,
|
|
||||||
bottom: 0,
|
|
||||||
height: '20%',
|
|
||||||
backgroundImage:
|
|
||||||
'linear-gradient(0deg, rgba(0,0,0,0.8) 0%, rgba(255,255,255,0) 100%)',
|
|
||||||
})}
|
|
||||||
></div>
|
|
||||||
<div
|
|
||||||
className={css({
|
|
||||||
position: 'absolute',
|
|
||||||
right: 0,
|
|
||||||
bottom: '0',
|
|
||||||
padding: '1rem',
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
variant="whiteCircle"
|
|
||||||
onPress={openEffects}
|
|
||||||
tooltip={t('effects.description')}
|
|
||||||
aria-label={t('effects.description')}
|
|
||||||
>
|
|
||||||
<RiImageCircleAiFill size={24} />
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<HStack justify="center" padding={1.5}>
|
<HStack justify="center" padding={1.5}>
|
||||||
<SelectToggleDevice
|
<SelectToggleDevice
|
||||||
|
|||||||
@@ -27,15 +27,17 @@ const Information = styled('div', {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export type EffectsConfigurationProps = {
|
||||||
|
videoTrack: LocalVideoTrack
|
||||||
|
onSubmit?: (processor?: BackgroundBlurProcessorInterface) => void
|
||||||
|
layout?: 'vertical' | 'horizontal'
|
||||||
|
}
|
||||||
|
|
||||||
export const EffectsConfiguration = ({
|
export const EffectsConfiguration = ({
|
||||||
videoTrack,
|
videoTrack,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
layout = 'horizontal',
|
layout = 'horizontal',
|
||||||
}: {
|
}: EffectsConfigurationProps) => {
|
||||||
videoTrack: LocalVideoTrack
|
|
||||||
onSubmit?: (processor?: BackgroundBlurProcessorInterface) => void
|
|
||||||
layout?: 'vertical' | 'horizontal'
|
|
||||||
}) => {
|
|
||||||
const videoRef = useRef<HTMLVideoElement>(null)
|
const videoRef = useRef<HTMLVideoElement>(null)
|
||||||
const { t } = useTranslation('rooms', { keyPrefix: 'effects' })
|
const { t } = useTranslation('rooms', { keyPrefix: 'effects' })
|
||||||
const [processorPending, setProcessorPending] = useState(false)
|
const [processorPending, setProcessorPending] = useState(false)
|
||||||
|
|||||||
Reference in New Issue
Block a user