♻️(frontend) enhance useSidePanel

Encapsulate all interactions with the layout store concerning the
side panel into a hook. This hook exposes a clear interface.
Each variable has a single responsability, with a clear naming.
This commit is contained in:
lebaudantoine
2024-10-14 17:56:22 +02:00
committed by aleb_the_flash
parent 0db36c788b
commit a47f1f92c4
4 changed files with 29 additions and 28 deletions

View File

@@ -1,4 +1,3 @@
import { useSnapshot } from 'valtio'
import { layoutStore } from '@/stores/layout' import { layoutStore } from '@/stores/layout'
import { css } from '@/styled-system/css' import { css } from '@/styled-system/css'
import { Heading } from 'react-aria-components' import { Heading } from 'react-aria-components'
@@ -100,20 +99,23 @@ const Panel = ({ isOpen, children }: PanelProps) => (
) )
export const SidePanel = () => { export const SidePanel = () => {
const layoutSnap = useSnapshot(layoutStore) const {
const sidePanel = layoutSnap.sidePanel activePanelId,
isParticipantsOpen,
const { isParticipantsOpen, isEffectsOpen, isChatOpen } = useSidePanel() isEffectsOpen,
isChatOpen,
isSidePanelOpen,
} = useSidePanel()
const { t } = useTranslation('rooms', { keyPrefix: 'sidePanel' }) const { t } = useTranslation('rooms', { keyPrefix: 'sidePanel' })
return ( return (
<StyledSidePanel <StyledSidePanel
title={t(`heading.${sidePanel}`)} title={t(`heading.${activePanelId}`)}
onClose={() => (layoutStore.sidePanel = null)} onClose={() => (layoutStore.activePanelId = null)}
closeButtonTooltip={t('closeButton', { closeButtonTooltip={t('closeButton', {
content: t(`content.${sidePanel}`), content: t(`content.${activePanelId}`),
})} })}
isClosed={!sidePanel} isClosed={!isSidePanelOpen}
> >
<Panel isOpen={isParticipantsOpen}> <Panel isOpen={isParticipantsOpen}>
<ParticipantsList /> <ParticipantsList />

View File

@@ -1,7 +1,7 @@
import { useSnapshot } from 'valtio' import { useSnapshot } from 'valtio'
import { layoutStore } from '@/stores/layout' import { layoutStore } from '@/stores/layout'
export enum SidePanel { export enum PanelId {
PARTICIPANTS = 'participants', PARTICIPANTS = 'participants',
EFFECTS = 'effects', EFFECTS = 'effects',
CHAT = 'chat', CHAT = 'chat',
@@ -9,30 +9,33 @@ export enum SidePanel {
export const useSidePanel = () => { export const useSidePanel = () => {
const layoutSnap = useSnapshot(layoutStore) const layoutSnap = useSnapshot(layoutStore)
const sidePanel = layoutSnap.sidePanel const activePanelId = layoutSnap.activePanelId
const isParticipantsOpen = sidePanel == SidePanel.PARTICIPANTS const isParticipantsOpen = activePanelId == PanelId.PARTICIPANTS
const isEffectsOpen = sidePanel == SidePanel.EFFECTS const isEffectsOpen = activePanelId == PanelId.EFFECTS
const isChatOpen = sidePanel == SidePanel.CHAT const isChatOpen = activePanelId == PanelId.CHAT
const isSidePanelOpen = !!activePanelId
const toggleParticipants = () => { const toggleParticipants = () => {
layoutStore.sidePanel = isParticipantsOpen ? null : SidePanel.PARTICIPANTS layoutStore.activePanelId = isParticipantsOpen ? null : PanelId.PARTICIPANTS
} }
const toggleChat = () => { const toggleChat = () => {
layoutStore.sidePanel = isChatOpen ? null : SidePanel.CHAT layoutStore.activePanelId = isChatOpen ? null : PanelId.CHAT
} }
const toggleEffects = () => { const toggleEffects = () => {
layoutStore.sidePanel = isEffectsOpen ? null : SidePanel.EFFECTS layoutStore.activePanelId = isEffectsOpen ? null : PanelId.EFFECTS
} }
return { return {
activePanelId,
toggleParticipants, toggleParticipants,
toggleChat, toggleChat,
toggleEffects, toggleEffects,
isChatOpen, isChatOpen,
isParticipantsOpen, isParticipantsOpen,
isEffectsOpen, isEffectsOpen,
isSidePanelOpen,
} }
} }

View File

@@ -23,12 +23,11 @@ import {
import { ControlBar } from './ControlBar' import { ControlBar } from './ControlBar'
import { styled } from '@/styled-system/jsx' import { styled } from '@/styled-system/jsx'
import { cva } from '@/styled-system/css' import { cva } from '@/styled-system/css'
import { useSnapshot } from 'valtio' import { MainNotificationToast } from '@/features/notifications/MainNotificationToast'
import { layoutStore } from '@/stores/layout'
import { FocusLayout } from '../components/FocusLayout' import { FocusLayout } from '../components/FocusLayout'
import { ParticipantTile } from '../components/ParticipantTile' import { ParticipantTile } from '../components/ParticipantTile'
import { SidePanel } from '../components/SidePanel' import { SidePanel } from '../components/SidePanel'
import { MainNotificationToast } from '@/features/notifications/MainNotificationToast' import { useSidePanel } from '../hooks/useSidePanel'
const LayoutWrapper = styled( const LayoutWrapper = styled(
'div', 'div',
@@ -147,10 +146,7 @@ export function VideoConference({ ...props }: VideoConferenceProps) {
]) ])
/* eslint-enable react-hooks/exhaustive-deps */ /* eslint-enable react-hooks/exhaustive-deps */
const layoutSnap = useSnapshot(layoutStore) const { isSidePanelOpen } = useSidePanel()
// todo - rename this variable
const sidePanel = layoutSnap.sidePanel
return ( return (
<div className="lk-video-conference" {...props}> <div className="lk-video-conference" {...props}>
@@ -163,7 +159,7 @@ export function VideoConference({ ...props }: VideoConferenceProps) {
// todo - extract these magic values into constant // todo - extract these magic values into constant
style={{ style={{
position: 'absolute', position: 'absolute',
inset: sidePanel inset: isSidePanelOpen
? 'var(--lk-grid-gap) calc(358px + 3rem) calc(80px + var(--lk-grid-gap)) 16px' ? 'var(--lk-grid-gap) calc(358px + 3rem) calc(80px + var(--lk-grid-gap)) 16px'
: 'var(--lk-grid-gap) var(--lk-grid-gap) calc(80px + var(--lk-grid-gap))', : 'var(--lk-grid-gap) var(--lk-grid-gap) calc(80px + var(--lk-grid-gap))',
transition: 'inset .5s cubic-bezier(0.4,0,0.2,1) 5ms', transition: 'inset .5s cubic-bezier(0.4,0,0.2,1) 5ms',

View File

@@ -1,12 +1,12 @@
import { proxy } from 'valtio' import { proxy } from 'valtio'
import { SidePanel } from '@/features/rooms/livekit/hooks/useSidePanel' import { PanelId } from '@/features/rooms/livekit/hooks/useSidePanel'
type State = { type State = {
showHeader: boolean showHeader: boolean
sidePanel: SidePanel | null activePanelId: PanelId | null
} }
export const layoutStore = proxy<State>({ export const layoutStore = proxy<State>({
showHeader: false, showHeader: false,
sidePanel: null, activePanelId: null,
}) })