From 4054489eafa605a992afc70915603d5c8c1f92c2 Mon Sep 17 00:00:00 2001 From: moonrailgun Date: Thu, 27 Jul 2023 00:00:38 +0800 Subject: [PATCH] feat: add fullscreen btn to make dom full screen --- .../src/components/FullScreenBtn.tsx | 32 +++++++++++++++++++ .../src/components/lib/FocusLayout.tsx | 10 ++++++ .../src/components/lib/ParticipantTile.tsx | 25 +++++++++++++++ .../src/components/lib/VideoConference.tsx | 3 +- 4 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 server/plugins/com.msgbyte.livekit/web/plugins/com.msgbyte.livekit/src/components/FullScreenBtn.tsx create mode 100644 server/plugins/com.msgbyte.livekit/web/plugins/com.msgbyte.livekit/src/components/lib/FocusLayout.tsx diff --git a/server/plugins/com.msgbyte.livekit/web/plugins/com.msgbyte.livekit/src/components/FullScreenBtn.tsx b/server/plugins/com.msgbyte.livekit/web/plugins/com.msgbyte.livekit/src/components/FullScreenBtn.tsx new file mode 100644 index 00000000..69aa6db9 --- /dev/null +++ b/server/plugins/com.msgbyte.livekit/web/plugins/com.msgbyte.livekit/src/components/FullScreenBtn.tsx @@ -0,0 +1,32 @@ +import { Icon } from '@capital/component'; +import React from 'react'; +import styled from 'styled-components'; + +const Root = styled.div.attrs({ + className: 'lk-button', +})` + position: absolute; + top: 0.25rem; + right: 2.25rem; + padding: 0.125rem; + font-size: 20px; + background-color: rgba(0, 0, 0, 0.5); + border-radius: calc(var(--lk-border-radius) / 2); + opacity: 0; + transition: opacity 0.2s ease-in-out; + transition-delay: 0.2s; + + .lk-participant-tile:hover & { + opacity: 1; + } +`; + +export const FullScreenBtn: React.FC> = + React.memo((props) => { + return ( + + + + ); + }); +FullScreenBtn.displayName = 'FullScreenBtn'; diff --git a/server/plugins/com.msgbyte.livekit/web/plugins/com.msgbyte.livekit/src/components/lib/FocusLayout.tsx b/server/plugins/com.msgbyte.livekit/web/plugins/com.msgbyte.livekit/src/components/lib/FocusLayout.tsx new file mode 100644 index 00000000..2b33cb66 --- /dev/null +++ b/server/plugins/com.msgbyte.livekit/web/plugins/com.msgbyte.livekit/src/components/lib/FocusLayout.tsx @@ -0,0 +1,10 @@ +import type { FocusLayoutProps } from '@livekit/components-react'; +import React from 'react'; +import { ParticipantTile } from './ParticipantTile'; + +export const FocusLayout: React.FC = React.memo( + ({ track, ...htmlProps }) => { + return ; + } +); +FocusLayout.displayName = 'FocusLayout'; diff --git a/server/plugins/com.msgbyte.livekit/web/plugins/com.msgbyte.livekit/src/components/lib/ParticipantTile.tsx b/server/plugins/com.msgbyte.livekit/web/plugins/com.msgbyte.livekit/src/components/lib/ParticipantTile.tsx index e617691e..501138ef 100644 --- a/server/plugins/com.msgbyte.livekit/web/plugins/com.msgbyte.livekit/src/components/lib/ParticipantTile.tsx +++ b/server/plugins/com.msgbyte.livekit/web/plugins/com.msgbyte.livekit/src/components/lib/ParticipantTile.tsx @@ -35,6 +35,8 @@ import { ScreenShareIcon } from './icons/ScreenShareIcon'; import { useSize } from '../../utils/useResizeObserver'; import { Translate } from '../../translate'; import { useMemo } from 'react'; +import { FullScreenBtn } from '../FullScreenBtn'; +import { useEvent } from '@capital/common'; /** @public */ export type ParticipantTileProps = React.HTMLAttributes & { @@ -176,6 +178,16 @@ export const ParticipantTile = ({ [trackRef.participant, layoutContext, trackRef.source] ); + const handleFullScreen = useEvent(() => { + if (containerEl.current) { + if (checkIsFullscreen()) { + document.exitFullscreen(); + } else { + containerEl.current.requestFullscreen(); + } + } + }); + const { width, height } = useSize(containerEl); const avatarSize = useMemo(() => { const min = Math.min(width, height); @@ -237,8 +249,21 @@ export const ParticipantTile = ({ )} + + + ); }; + +function checkIsFullscreen(): boolean { + return ( + document.fullscreenElement || + (document as any).msFullscreenElement || + (document as any).mozFullScreenElement || + (document as any).webkitFullscreenElement || + false + ); +} diff --git a/server/plugins/com.msgbyte.livekit/web/plugins/com.msgbyte.livekit/src/components/lib/VideoConference.tsx b/server/plugins/com.msgbyte.livekit/web/plugins/com.msgbyte.livekit/src/components/lib/VideoConference.tsx index 51635f4a..692c3455 100644 --- a/server/plugins/com.msgbyte.livekit/web/plugins/com.msgbyte.livekit/src/components/lib/VideoConference.tsx +++ b/server/plugins/com.msgbyte.livekit/web/plugins/com.msgbyte.livekit/src/components/lib/VideoConference.tsx @@ -14,7 +14,6 @@ import { RoomEvent, Track } from 'livekit-client'; import type { TrackReferenceOrPlaceholder } from '@livekit/components-core'; import { ConnectionStateToast, - FocusLayout, FocusLayoutContainer, GridLayout, LayoutContextProvider, @@ -28,6 +27,7 @@ import { ParticipantTile } from './ParticipantTile'; import { CarouselLayout } from './CarouselLayout'; import { ControlBar } from './ControlBar'; import { Chat } from './Chat'; +import { FocusLayout } from './FocusLayout'; /** * @public @@ -137,6 +137,7 @@ export const VideoConference: React.FC = React.memo( + {focusTrack && }