mirror of
https://github.com/suitenumerique/meet.git
synced 2026-08-28 11:16:58 +00:00
✨(feat) connect PiP to room and options menu
wire room-level PiP state to the options menu
This commit is contained in:
@@ -153,4 +153,3 @@ export const DocumentPiPPortal = ({
|
|||||||
|
|
||||||
return portal
|
return portal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,4 +71,3 @@ const PipControlsRight = styled('div', {
|
|||||||
right: '1.35rem',
|
right: '1.35rem',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -107,4 +107,3 @@ const PipGridWrapper = styled('div', {
|
|||||||
height: '100%',
|
height: '100%',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -15,4 +15,3 @@ export const RoomPiP = () => {
|
|||||||
</DocumentPiPPortal>
|
</DocumentPiPPortal>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-4
@@ -9,8 +9,7 @@ import { PipOptionsMenu } from './PipOptionsMenu'
|
|||||||
export const OptionsButton = () => {
|
export const OptionsButton = () => {
|
||||||
const { t } = useTranslation('rooms')
|
const { t } = useTranslation('rooms')
|
||||||
const portalContainer = useOverlayPortalContainer()
|
const portalContainer = useOverlayPortalContainer()
|
||||||
const isInPiP =
|
const isInPiP = portalContainer && portalContainer.ownerDocument !== document
|
||||||
portalContainer && portalContainer.ownerDocument !== document
|
|
||||||
const [isOpen, setIsOpen] = useState(false)
|
const [isOpen, setIsOpen] = useState(false)
|
||||||
const wrapperRef = useRef<HTMLDivElement>(null)
|
const wrapperRef = useRef<HTMLDivElement>(null)
|
||||||
|
|
||||||
@@ -33,8 +32,6 @@ export const OptionsButton = () => {
|
|||||||
}
|
}
|
||||||
}, [isInPiP, isOpen])
|
}, [isInPiP, isOpen])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (isInPiP) {
|
if (isInPiP) {
|
||||||
return (
|
return (
|
||||||
<PipOptionsMenu
|
<PipOptionsMenu
|
||||||
|
|||||||
-1
@@ -21,4 +21,3 @@ export const PictureInPictureMenuItem = () => {
|
|||||||
</MenuItem>
|
</MenuItem>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -30,10 +30,10 @@ export const PipOptionsMenu = ({
|
|||||||
const target = event.target as HTMLElement | null
|
const target = event.target as HTMLElement | null
|
||||||
const wrapper = wrapperRef.current
|
const wrapper = wrapperRef.current
|
||||||
if (!wrapper || !target) return
|
if (!wrapper || !target) return
|
||||||
|
|
||||||
// Don't close if clicking the trigger button
|
// Don't close if clicking the trigger button
|
||||||
if (wrapper.querySelector('button')?.contains(target)) return
|
if (wrapper.querySelector('button')?.contains(target)) return
|
||||||
|
|
||||||
// Close if clicking a menu item (action will have fired)
|
// Close if clicking a menu item (action will have fired)
|
||||||
if (target.closest('[role="menuitem"]')) {
|
if (target.closest('[role="menuitem"]')) {
|
||||||
// Use requestAnimationFrame to ensure action completes first, without visible delay
|
// Use requestAnimationFrame to ensure action completes first, without visible delay
|
||||||
@@ -83,4 +83,4 @@ export const PipOptionsMenu = ({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,4 +64,3 @@ export const PipLateralMenu = () => {
|
|||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,10 +19,7 @@ export const RoomPiPProvider = ({
|
|||||||
|
|
||||||
const open = useCallback(() => setIsOpen(true), [])
|
const open = useCallback(() => setIsOpen(true), [])
|
||||||
const close = useCallback(() => setIsOpen(false), [])
|
const close = useCallback(() => setIsOpen(false), [])
|
||||||
const toggle = useCallback(
|
const toggle = useCallback(() => setIsOpen((current) => !current), [])
|
||||||
() => setIsOpen((current) => !current),
|
|
||||||
[]
|
|
||||||
)
|
|
||||||
|
|
||||||
const value = useMemo(
|
const value = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
@@ -36,9 +33,6 @@ export const RoomPiPProvider = ({
|
|||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RoomPiPContext.Provider value={value}>
|
<RoomPiPContext.Provider value={value}>{children}</RoomPiPContext.Provider>
|
||||||
{children}
|
|
||||||
</RoomPiPContext.Provider>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,4 +9,3 @@ export type RoomPiPContextValue = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const RoomPiPContext = createContext<RoomPiPContextValue | null>(null)
|
export const RoomPiPContext = createContext<RoomPiPContextValue | null>(null)
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
import { useCallback, useEffect, useMemo, useState } from 'react'
|
import { useCallback, useEffect, useMemo, useState } from 'react'
|
||||||
|
|
||||||
type DocumentPictureInPicture = {
|
type DocumentPictureInPicture = {
|
||||||
requestWindow: (options?: { width?: number; height?: number }) => Promise<Window>
|
requestWindow: (options?: {
|
||||||
|
width?: number
|
||||||
|
height?: number
|
||||||
|
}) => Promise<Window>
|
||||||
}
|
}
|
||||||
|
|
||||||
type WindowWithDocumentPiP = Window & {
|
type WindowWithDocumentPiP = Window & {
|
||||||
@@ -67,4 +70,3 @@ export const useDocumentPiP = ({
|
|||||||
closePiP,
|
closePiP,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,4 +8,3 @@ export const useRoomPiP = () => {
|
|||||||
}
|
}
|
||||||
return context
|
return context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export const Menu = ({
|
|||||||
const [trigger, menu] = children
|
const [trigger, menu] = children
|
||||||
const boundaryElement = useOverlayBoundaryElement()
|
const boundaryElement = useOverlayBoundaryElement()
|
||||||
const portalContainer = useOverlayPortalContainer()
|
const portalContainer = useOverlayPortalContainer()
|
||||||
|
|
||||||
// Detect if we're in PiP: portal container is in a different document than the main window
|
// Detect if we're in PiP: portal container is in a different document than the main window
|
||||||
const isInPiP = useMemo(
|
const isInPiP = useMemo(
|
||||||
() =>
|
() =>
|
||||||
|
|||||||
@@ -134,10 +134,7 @@ const Tooltip = ({
|
|||||||
children: ReactNode
|
children: ReactNode
|
||||||
} & Partial<Omit<TooltipProps, 'children'>>) => {
|
} & Partial<Omit<TooltipProps, 'children'>>) => {
|
||||||
return (
|
return (
|
||||||
<StyledTooltip
|
<StyledTooltip arrowBoundaryOffset={arrowBoundaryOffset ?? 0} {...props}>
|
||||||
arrowBoundaryOffset={arrowBoundaryOffset ?? 0}
|
|
||||||
{...props}
|
|
||||||
>
|
|
||||||
<TooltipArrow />
|
<TooltipArrow />
|
||||||
{children}
|
{children}
|
||||||
</StyledTooltip>
|
</StyledTooltip>
|
||||||
|
|||||||
@@ -82,7 +82,8 @@ export const VisualOnlyTooltip = ({
|
|||||||
>
|
>
|
||||||
{wrappedChild}
|
{wrappedChild}
|
||||||
</div>
|
</div>
|
||||||
{tooltipData && portalContainer &&
|
{tooltipData &&
|
||||||
|
portalContainer &&
|
||||||
createPortal(
|
createPortal(
|
||||||
<div
|
<div
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
|
|||||||
@@ -22,4 +22,3 @@ export const useOverlayBoundaryElement = () => {
|
|||||||
return undefined
|
return undefined
|
||||||
}, [portalContainer])
|
}, [portalContainer])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user