mirror of
https://github.com/suitenumerique/meet.git
synced 2026-08-21 15:47:09 +00:00
fixup! ♻️(frontend) normalize PiP component patterns
This commit is contained in:
@@ -14,17 +14,21 @@ import { usePipElementSize } from '../hooks/usePipElementSize'
|
|||||||
import { PipOptionsMenu } from './controls/PipOptionsMenu'
|
import { PipOptionsMenu } from './controls/PipOptionsMenu'
|
||||||
import { PipReactionsToggle } from './PipReactionsToggle'
|
import { PipReactionsToggle } from './PipReactionsToggle'
|
||||||
|
|
||||||
|
export const CollapsibleControls = {
|
||||||
|
HAND: 'hand',
|
||||||
|
SUBTITLES: 'subtitles',
|
||||||
|
SCREEN_SHARE: 'screenShare',
|
||||||
|
REACTIONS: 'reactions',
|
||||||
|
} as const
|
||||||
|
|
||||||
export type CollapsibleControl =
|
export type CollapsibleControl =
|
||||||
| 'hand'
|
(typeof CollapsibleControls)[keyof typeof CollapsibleControls]
|
||||||
| 'subtitles'
|
|
||||||
| 'screenShare'
|
|
||||||
| 'reactions'
|
|
||||||
|
|
||||||
const COLLAPSE_ORDER: CollapsibleControl[] = [
|
const COLLAPSE_ORDER: CollapsibleControl[] = [
|
||||||
'hand',
|
CollapsibleControls.HAND,
|
||||||
'subtitles',
|
CollapsibleControls.SUBTITLES,
|
||||||
'screenShare',
|
CollapsibleControls.SCREEN_SHARE,
|
||||||
'reactions',
|
CollapsibleControls.REACTIONS,
|
||||||
]
|
]
|
||||||
|
|
||||||
const BUTTON_SLOT = 50
|
const BUTTON_SLOT = 50
|
||||||
@@ -39,7 +43,7 @@ const getHiddenControls = (
|
|||||||
|
|
||||||
const collapsible = showScreenShare
|
const collapsible = showScreenShare
|
||||||
? COLLAPSE_ORDER
|
? COLLAPSE_ORDER
|
||||||
: COLLAPSE_ORDER.filter((c) => c !== 'screenShare')
|
: COLLAPSE_ORDER.filter((c) => c !== CollapsibleControls.SCREEN_SHARE)
|
||||||
|
|
||||||
const available = containerWidth - ESSENTIAL_WIDTH
|
const available = containerWidth - ESSENTIAL_WIDTH
|
||||||
const maxVisible = Math.max(0, Math.floor(available / BUTTON_SLOT))
|
const maxVisible = Math.max(0, Math.floor(available / BUTTON_SLOT))
|
||||||
@@ -84,10 +88,10 @@ export const PipControlBar = ({
|
|||||||
<PipControlsCenter>
|
<PipControlsCenter>
|
||||||
<AudioDevicesControl hideMenu />
|
<AudioDevicesControl hideMenu />
|
||||||
<VideoDeviceControl hideMenu />
|
<VideoDeviceControl hideMenu />
|
||||||
{!hidden.has('reactions') && <PipReactionsToggle />}
|
{!hidden.has(CollapsibleControls.REACTIONS) && <PipReactionsToggle />}
|
||||||
{showScreenShare && !hidden.has('screenShare') && <ScreenShareToggle />}
|
{showScreenShare && !hidden.has(CollapsibleControls.SCREEN_SHARE) && <ScreenShareToggle />}
|
||||||
{!hidden.has('subtitles') && <SubtitlesToggle />}
|
{!hidden.has(CollapsibleControls.SUBTITLES) && <SubtitlesToggle />}
|
||||||
{!hidden.has('hand') && <HandToggle />}
|
{!hidden.has(CollapsibleControls.HAND) && <HandToggle />}
|
||||||
<PipOptionsMenu overflowControls={hidden} />
|
<PipOptionsMenu overflowControls={hidden} />
|
||||||
<LeaveButton />
|
<LeaveButton />
|
||||||
<StartMediaButton />
|
<StartMediaButton />
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { Menu as RACMenu, MenuSection } from 'react-aria-components'
|
import { Menu as RACMenu, MenuSection } from 'react-aria-components'
|
||||||
import { useTranslation } from 'react-i18next'
|
|
||||||
import { Separator } from '@/primitives/Separator'
|
import { Separator } from '@/primitives/Separator'
|
||||||
import { FeedbackMenuItem } from '@/features/rooms/livekit/components/controls/Options/FeedbackMenuItem'
|
import { FeedbackMenuItem } from '@/features/rooms/livekit/components/controls/Options/FeedbackMenuItem'
|
||||||
import { EffectsMenuItem } from '@/features/rooms/livekit/components/controls/Options/EffectsMenuItem'
|
import { EffectsMenuItem } from '@/features/rooms/livekit/components/controls/Options/EffectsMenuItem'
|
||||||
@@ -16,7 +15,6 @@ type PipOptionsMenuItemsProps = {
|
|||||||
export const PipOptionsMenuItems = ({
|
export const PipOptionsMenuItems = ({
|
||||||
overflowControls,
|
overflowControls,
|
||||||
}: PipOptionsMenuItemsProps) => {
|
}: PipOptionsMenuItemsProps) => {
|
||||||
const { t } = useTranslation('rooms')
|
|
||||||
const hasOverflow = overflowControls && overflowControls.size > 0
|
const hasOverflow = overflowControls && overflowControls.size > 0
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -29,7 +27,7 @@ export const PipOptionsMenuItems = ({
|
|||||||
{hasOverflow && (
|
{hasOverflow && (
|
||||||
<>
|
<>
|
||||||
<MenuSection>
|
<MenuSection>
|
||||||
<PipOverflowItems overflowControls={overflowControls} t={t} />
|
<PipOverflowItems overflowControls={overflowControls} />
|
||||||
</MenuSection>
|
</MenuSection>
|
||||||
<Separator />
|
<Separator />
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import React from 'react'
|
||||||
import { MenuItem } from 'react-aria-components'
|
import { MenuItem } from 'react-aria-components'
|
||||||
import {
|
import {
|
||||||
RiHand,
|
RiHand,
|
||||||
@@ -5,57 +6,60 @@ import {
|
|||||||
RiArrowUpLine,
|
RiArrowUpLine,
|
||||||
RiEmotionLine,
|
RiEmotionLine,
|
||||||
} from '@remixicon/react'
|
} from '@remixicon/react'
|
||||||
import { TFunction } from 'i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { Track } from 'livekit-client'
|
||||||
import { pipLayoutStore } from '@/features/pip/stores/pipLayoutStore'
|
import { pipLayoutStore } from '@/features/pip/stores/pipLayoutStore'
|
||||||
import { menuRecipe } from '@/primitives/menuRecipe'
|
import { menuRecipe } from '@/primitives/menuRecipe'
|
||||||
import { useRoomContext } from '@livekit/components-react'
|
import { useRoomContext, useTrackToggle } from '@livekit/components-react'
|
||||||
import { useRaisedHand } from '@/features/rooms/livekit/hooks/useRaisedHand'
|
import { useRaisedHand } from '@/features/rooms/livekit/hooks/useRaisedHand'
|
||||||
import { useSubtitles } from '@/features/subtitle/hooks/useSubtitles'
|
import { useSubtitles } from '@/features/subtitle/hooks/useSubtitles'
|
||||||
import { useAreSubtitlesAvailable } from '@/features/subtitle/hooks/useAreSubtitlesAvailable'
|
import { useAreSubtitlesAvailable } from '@/features/subtitle/hooks/useAreSubtitlesAvailable'
|
||||||
import { useSnapshot } from 'valtio'
|
import { useSnapshot } from 'valtio'
|
||||||
import type { CollapsibleControl } from '../PipControlBar'
|
import { CollapsibleControls, type CollapsibleControl } from '../PipControlBar'
|
||||||
|
|
||||||
type PipOverflowItemsProps = {
|
type PipOverflowItemsProps = {
|
||||||
overflowControls: Set<CollapsibleControl>
|
overflowControls: Set<CollapsibleControl>
|
||||||
t: TFunction<'rooms'>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PipOverflowItems = ({
|
export const PipOverflowItems = ({
|
||||||
overflowControls,
|
overflowControls,
|
||||||
t,
|
|
||||||
}: PipOverflowItemsProps) => {
|
}: PipOverflowItemsProps) => {
|
||||||
|
const { t } = useTranslation('rooms')
|
||||||
const room = useRoomContext()
|
const room = useRoomContext()
|
||||||
const { isHandRaised, toggleRaisedHand } = useRaisedHand({
|
const { isHandRaised, toggleRaisedHand } = useRaisedHand({
|
||||||
participant: room.localParticipant,
|
participant: room.localParticipant,
|
||||||
})
|
})
|
||||||
const { areSubtitlesOpen, toggleSubtitles } = useSubtitles()
|
const { areSubtitlesOpen, toggleSubtitles } = useSubtitles()
|
||||||
const areSubtitlesAvailable = useAreSubtitlesAvailable()
|
const areSubtitlesAvailable = useAreSubtitlesAvailable()
|
||||||
const pipSnap = useSnapshot(pipLayoutStore)
|
const { buttonProps: screenShareProps, enabled: isScreenSharing } =
|
||||||
|
useTrackToggle({
|
||||||
|
source: Track.Source.ScreenShare,
|
||||||
|
captureOptions: { audio: true, selfBrowserSurface: 'include' },
|
||||||
|
})
|
||||||
|
const pipLayoutSnap = useSnapshot(pipLayoutStore)
|
||||||
const toggleReactions = () => {
|
const toggleReactions = () => {
|
||||||
pipLayoutStore.showReactionsToolbar = !pipSnap.showReactionsToolbar
|
pipLayoutStore.showReactionsToolbar = !pipLayoutSnap.showReactionsToolbar
|
||||||
}
|
}
|
||||||
const itemClass = menuRecipe({ icon: true, variant: 'dark' }).item
|
const itemClass = menuRecipe({ icon: true, variant: 'dark' }).item
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{overflowControls.has('reactions') && (
|
{overflowControls.has(CollapsibleControls.REACTIONS) && (
|
||||||
<MenuItem onAction={toggleReactions} className={itemClass}>
|
<MenuItem onAction={toggleReactions} className={itemClass}>
|
||||||
<RiEmotionLine size={20} />
|
<RiEmotionLine size={20} />
|
||||||
{t('controls.reactions.button')}
|
{t('controls.reactions.button')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)}
|
)}
|
||||||
{overflowControls.has('screenShare') && (
|
{overflowControls.has(CollapsibleControls.SCREEN_SHARE) && (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
onAction={() => {
|
onAction={() => screenShareProps.onClick?.({} as React.MouseEvent<HTMLButtonElement>)}
|
||||||
/* screen share requires track toggle, handled externally */
|
|
||||||
}}
|
|
||||||
className={itemClass}
|
className={itemClass}
|
||||||
>
|
>
|
||||||
<RiArrowUpLine size={20} />
|
<RiArrowUpLine size={20} />
|
||||||
{t('controls.screenShare.start')}
|
{t(isScreenSharing ? 'controls.screenShare.stop' : 'controls.screenShare.start')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)}
|
)}
|
||||||
{overflowControls.has('subtitles') && areSubtitlesAvailable && (
|
{overflowControls.has(CollapsibleControls.SUBTITLES) && areSubtitlesAvailable && (
|
||||||
<MenuItem onAction={toggleSubtitles} className={itemClass}>
|
<MenuItem onAction={toggleSubtitles} className={itemClass}>
|
||||||
<RiClosedCaptioningLine size={20} />
|
<RiClosedCaptioningLine size={20} />
|
||||||
{areSubtitlesOpen
|
{areSubtitlesOpen
|
||||||
@@ -63,7 +67,7 @@ export const PipOverflowItems = ({
|
|||||||
: t('controls.subtitles.closed')}
|
: t('controls.subtitles.closed')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)}
|
)}
|
||||||
{overflowControls.has('hand') && (
|
{overflowControls.has(CollapsibleControls.HAND) && (
|
||||||
<MenuItem onAction={toggleRaisedHand} className={itemClass}>
|
<MenuItem onAction={toggleRaisedHand} className={itemClass}>
|
||||||
<RiHand size={20} />
|
<RiHand size={20} />
|
||||||
{isHandRaised ? t('controls.hand.lower') : t('controls.hand.raise')}
|
{isHandRaised ? t('controls.hand.lower') : t('controls.hand.raise')}
|
||||||
|
|||||||
Reference in New Issue
Block a user