diff --git a/src/frontend/src/features/rooms/livekit/components/Info.tsx b/src/frontend/src/features/rooms/livekit/components/Info.tsx index 08d3c1ff..f45e794a 100644 --- a/src/frontend/src/features/rooms/livekit/components/Info.tsx +++ b/src/frontend/src/features/rooms/livekit/components/Info.tsx @@ -1,5 +1,5 @@ import { useTranslation } from 'react-i18next' -import { useMemo } from 'react' +import { useEffect, useMemo, useRef } from 'react' import { VStack } from '@/styled-system/jsx' import { css } from '@/styled-system/css' import { RiCheckLine, RiFileCopyLine } from '@remixicon/react' @@ -9,16 +9,24 @@ import { useRoomData } from '../hooks/useRoomData' import { formatPinCode } from '../../utils/telephony' import { useTelephony } from '../hooks/useTelephony' import { useCopyRoomToClipboard } from '../hooks/useCopyRoomToClipboard' -import { useSidePanel } from '../hooks/useSidePanel' -import { useRestoreFocus } from '@/hooks/useRestoreFocus' -import { useSidePanelRef } from '../hooks/useSidePanelRef' -import { useSidePanelTriggers } from '../hooks/useSidePanelTriggers' + +const useFocusOnOpen = ({ ref, key }) => { + useEffect(() => { + requestAnimationFrame(() => { + const panel = ref.current + if (panel) { + const firstButton = panel.querySelector(key) + if (firstButton) { + firstButton.focus({ preventScroll: true }) + } + } + }) + }, []) +} export const Info = () => { const { t } = useTranslation('rooms', { keyPrefix: 'info' }) - const { isInfoOpen } = useSidePanel() - const panelRef = useSidePanelRef() - const { getTrigger } = useSidePanelTriggers() + const panelRef = useRef() const data = useRoomData() const roomUrl = getRouteUrl('room', data?.slug) @@ -31,26 +39,7 @@ export const Info = () => { const { isCopied, copyRoomToClipboard } = useCopyRoomToClipboard(data) - // Restore focus to the element that opened the Info panel - useRestoreFocus(isInfoOpen, { - resolveTrigger: (activeEl) => getTrigger('info') ?? activeEl, - // Focus the first focusable element when the panel opens - onOpened: () => { - requestAnimationFrame(() => { - const panel = panelRef.current - if (panel) { - const firstButton = panel.querySelector( - '[data-attr="copy-info-sidepanel"]' - ) - if (firstButton) { - firstButton.focus({ preventScroll: true }) - } - } - }) - }, - restoreFocusRaf: true, - preventScroll: true, - }) + useFocusOnOpen({ ref: panelRef, key: '[data-attr="copy-info-sidepanel"]' }) return (
{ flexGrow={1} flexDirection="column" alignItems="start" + ref={panelRef} > { - + diff --git a/src/frontend/src/features/rooms/livekit/components/controls/InfoToggle.tsx b/src/frontend/src/features/rooms/livekit/components/controls/InfoToggle.tsx index 8578665d..839b1b09 100644 --- a/src/frontend/src/features/rooms/livekit/components/controls/InfoToggle.tsx +++ b/src/frontend/src/features/rooms/livekit/components/controls/InfoToggle.tsx @@ -1,4 +1,4 @@ -import { useCallback } from 'react' +import { useCallback, useRef } from 'react' import { useTranslation } from 'react-i18next' import { RiInformationLine } from '@remixicon/react' import { css } from '@/styled-system/css' @@ -14,14 +14,17 @@ export const InfoToggle = ({ const { t } = useTranslation('rooms', { keyPrefix: 'controls.info' }) const { isInfoOpen, toggleInfo } = useSidePanel() - const { setTrigger } = useSidePanelTriggers() + // const { setTrigger } = useSidePanelTriggers() const tooltipLabel = isInfoOpen ? 'open' : 'closed' - const setInfoTriggerRef = useCallback( - (el: HTMLElement | null) => { - setTrigger('info', el) - }, - [setTrigger] - ) + + const wip = useRef() + + // const setInfoTriggerRef = useCallback( + // (el: HTMLElement | null) => { + // setTrigger('info', el) + // }, + // [setTrigger] + // ) return (
{ - toggleInfo() + toggleInfo(wip) onPress?.(e) }} data-attr={`controls-info-${tooltipLabel}`} diff --git a/src/frontend/src/features/rooms/livekit/hooks/useSidePanel.ts b/src/frontend/src/features/rooms/livekit/hooks/useSidePanel.ts index 96b125e9..00420869 100644 --- a/src/frontend/src/features/rooms/livekit/hooks/useSidePanel.ts +++ b/src/frontend/src/features/rooms/livekit/hooks/useSidePanel.ts @@ -1,5 +1,6 @@ -import { useSnapshot } from 'valtio' +import { ref, useSnapshot } from 'valtio' import { layoutStore } from '@/stores/layout' +import { useEffect } from 'react' export enum PanelId { PARTICIPANTS = 'participants', @@ -56,8 +57,13 @@ export const useSidePanel = () => { if (layoutSnap.activeSubPanelId) layoutStore.activeSubPanelId = null } - const toggleInfo = () => { + const toggleInfo = (wip) => { layoutStore.activePanelId = isInfoOpen ? null : PanelId.INFO + + if (!isInfoOpen) { + layoutStore.genericRef = ref(wip) + } + if (layoutSnap.activeSubPanelId) layoutStore.activeSubPanelId = null } @@ -71,6 +77,18 @@ export const useSidePanel = () => { layoutStore.activePanelId = PanelId.TOOLS } + useEffect(() => { + if (!layoutSnap.activePanelId) { + console.log('$$prout closing') + const trigger = layoutSnap?.genericRef?.current + console.log(trigger) + if (trigger) { + trigger.focus({ preventScroll: true }) + trigger.setAttribute('data-restore-focus-visible', '') + } + } + }, [layoutSnap.activePanelId, layoutSnap?.genericRef]) + return { activePanelId, activeSubPanelId, diff --git a/src/frontend/src/stores/layout.ts b/src/frontend/src/stores/layout.ts index b04a24b6..154d5b42 100644 --- a/src/frontend/src/stores/layout.ts +++ b/src/frontend/src/stores/layout.ts @@ -10,6 +10,7 @@ type State = { showSubtitles: boolean activePanelId: PanelId | null activeSubPanelId: SubPanelId | null + genericRef: HTMLElement | null } export const layoutStore = proxy({ @@ -18,4 +19,5 @@ export const layoutStore = proxy({ showSubtitles: false, activePanelId: null, activeSubPanelId: null, + genericRef: null, })