feat: 라이브 강의 헤더 변경

This commit is contained in:
jhynsoo 2024-08-05 13:10:11 +09:00
parent a8069bb562
commit 2106a35b81
5 changed files with 80 additions and 103 deletions

View File

@ -5,9 +5,8 @@ import HomePage from './pages/HomePage';
import NotFoundPage from './pages/NotFoundPage';
import { lazy } from 'react';
import MyPageLayout from './components/Layout/MyPageLayout';
import { LiveLayout } from './components/Layout';
import LivePage from './pages/LivePage';
const LivePage = lazy(async () => await import('./pages/LivePage'));
const LectureLayout = lazy(async () => await import('./components/Layout/LectureLayout'));
const LearningLectureDetailPage = lazy(async () => await import('./pages/LearningLectureDetailPage'));
const NoticeListPage = lazy(async () => await import('./pages/NoticeListPage'));
@ -34,13 +33,7 @@ const QuizsetDetailPage = lazy(async () => await import('./pages/QuizsetDetailPa
const router = createBrowserRouter([
{
path: 'live/:roomId',
element: <LiveLayout />,
children: [
{
index: true,
element: <LivePage />,
},
],
element: <LivePage />,
},
{
path: '',

View File

@ -1,3 +1,4 @@
import styles from './LiveRoom.module.css';
import { isEqualTrackRef, isTrackReference } from '@livekit/components-core';
import {
CarouselLayout,
@ -11,7 +12,9 @@ import {
RoomAudioRenderer,
useCreateLayoutContext,
usePinnedTracks,
useRoomInfo,
useTracks,
useParticipants,
} from '@livekit/components-react';
import { RoomEvent, Track } from 'livekit-client';
import { useEffect, useRef } from 'react';
@ -20,6 +23,10 @@ import ChatRoom from '../ChatRoom/ChatRoom';
export default function LiveRoom() {
const lastAutoFocusedScreenShareTrack = useRef(null);
// get livekit identity
const room = useRoomInfo();
const participants = useParticipants();
const tracks = useTracks(
[
{ source: Track.Source.Camera, withPlaceholder: true },
@ -69,31 +76,40 @@ export default function LiveRoom() {
]);
return (
<div className="lk-video-conference">
<LayoutContextProvider value={layoutContext}>
<div className="lk-video-conference-inner">
{!focusTrack ? (
<div className="lk-grid-layout-wrapper">
<GridLayout tracks={tracks}>
<ParticipantTile />
</GridLayout>
</div>
) : (
<div className="lk-focus-layout-wrapper">
<FocusLayoutContainer>
<CarouselLayout tracks={carouselTracks}>
<ParticipantTile />
</CarouselLayout>
{focusTrack && <FocusLayout trackRef={focusTrack} />}
</FocusLayoutContainer>
</div>
)}
<ControlBar controls={{ chat: false, leave: false }} />
<div className={styles.wrapper}>
<header className={styles.header}>
<h1 className={styles.title}>{room.name}</h1>
<div className={styles.roomInfo}>
<span>참가자</span>
<span>{participants.length}</span>
</div>
<ChatRoom />
</LayoutContextProvider>
<RoomAudioRenderer />
<ConnectionStateToast />
</header>
<div className="lk-video-conference">
<LayoutContextProvider value={layoutContext}>
<div className="lk-video-conference-inner">
{!focusTrack ? (
<div className="lk-grid-layout-wrapper">
<GridLayout tracks={tracks}>
<ParticipantTile />
</GridLayout>
</div>
) : (
<div className="lk-focus-layout-wrapper">
<FocusLayoutContainer>
<CarouselLayout tracks={carouselTracks}>
<ParticipantTile />
</CarouselLayout>
{focusTrack && <FocusLayout trackRef={focusTrack} />}
</FocusLayoutContainer>
</div>
)}
<ControlBar controls={{ chat: false, leave: false }} />
</div>
<ChatRoom />
</LayoutContextProvider>
<RoomAudioRenderer />
<ConnectionStateToast />
</div>
</div>
);
}

View File

@ -1,67 +1,32 @@
.main {
.wrapper {
display: flex;
flex-direction: column;
width: 100vw;
height: 100vh;
}
.videoWrapper {
flex: 0 0 auto;
display: flex;
overflow-x: auto;
height: 80px;
gap: 10px;
padding: 10px;
border-bottom: 1px solid var(--border-color);
box-sizing: border-box;
& > audio {
display: none;
}
&::-webkit-scrollbar {
height: 6px;
}
&::-webkit-scrollbar-thumb {
background-color: var(--text-color-tertiary);
border-radius: 6px;
}
}
.mainContent {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
box-sizing: border-box;
& > video {
width: 100%;
height: calc(100vh - 208px);
object-fit: contain;
box-sizing: border-box;
}
}
.controlBar {
.header {
display: flex;
justify-content: space-between;
align-items: center;
height: 80px;
border-top: 1px solid var(--border-color);
box-sizing: border-box;
& > button {
background-color: var(--background-color-secondary);
color: var(--text-color-primary);
border: none;
border-radius: 4px;
padding: 8px 16px;
cursor: pointer;
transition: background-color 0.2s;
&:hover {
background-color: var(--background-color-tertiary);
}
}
width: 100%;
height: 48px;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.title {
padding: 0 16px;
font-size: 14px;
line-height: 1.4;
font-weight: 500;
}
.roomInfo {
display: flex;
align-items: center;
gap: 4px;
padding: 0 16px;
font-size: 12px;
line-height: 1.4;
font-weight: 500;
}

View File

@ -6,6 +6,7 @@ import instance from '../../utils/axios/instance';
import { API_URL, ROOM_URL } from '../../constants';
import useBoundStore from '../../store';
import '@livekit/components-styles';
import LoadingIndicator from '../../components/LoadingIndicator.jsx/LoadingIndicator';
export default function LivePage() {
const { roomId } = useParams();
@ -26,16 +27,16 @@ export default function LivePage() {
}
}, [generateToken, liveToken]);
return (
liveToken && (
<LiveKitRoom
token={liveToken}
serverUrl={ROOM_URL}
connect={true}
data-lk-theme="default"
>
<LiveRoom />
</LiveKitRoom>
)
return liveToken ? (
<LiveKitRoom
token={liveToken}
serverUrl={ROOM_URL}
connect={true}
data-lk-theme="default"
>
<LiveRoom />
</LiveKitRoom>
) : (
<LoadingIndicator fill />
);
}

View File

@ -1,4 +1,6 @@
export const liveSlice = (set) => ({
liveToken: null,
setLiveToken: (liveToken) => set({ liveToken }),
participants: 0,
setParticipants: (participants) => set({ participants }),
});