Merge branch 'fe/liveHeader' into 'frontend'
feat: 라이브 강의 헤더 변경 See merge request s11-webmobile1-sub2/S11P12A701!41
This commit is contained in:
commit
fedebaeb0f
@ -5,9 +5,8 @@ import HomePage from './pages/HomePage';
|
|||||||
import NotFoundPage from './pages/NotFoundPage';
|
import NotFoundPage from './pages/NotFoundPage';
|
||||||
import { lazy } from 'react';
|
import { lazy } from 'react';
|
||||||
import MyPageLayout from './components/Layout/MyPageLayout';
|
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 LectureLayout = lazy(async () => await import('./components/Layout/LectureLayout'));
|
||||||
const LearningLectureDetailPage = lazy(async () => await import('./pages/LearningLectureDetailPage'));
|
const LearningLectureDetailPage = lazy(async () => await import('./pages/LearningLectureDetailPage'));
|
||||||
const NoticeListPage = lazy(async () => await import('./pages/NoticeListPage'));
|
const NoticeListPage = lazy(async () => await import('./pages/NoticeListPage'));
|
||||||
@ -34,14 +33,8 @@ const QuizsetDetailPage = lazy(async () => await import('./pages/QuizsetDetailPa
|
|||||||
const router = createBrowserRouter([
|
const router = createBrowserRouter([
|
||||||
{
|
{
|
||||||
path: 'live/:roomId',
|
path: 'live/:roomId',
|
||||||
element: <LiveLayout />,
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
index: true,
|
|
||||||
element: <LivePage />,
|
element: <LivePage />,
|
||||||
},
|
},
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
element: <PageLayout />,
|
element: <PageLayout />,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import styles from './LiveRoom.module.css';
|
||||||
import { isEqualTrackRef, isTrackReference } from '@livekit/components-core';
|
import { isEqualTrackRef, isTrackReference } from '@livekit/components-core';
|
||||||
import {
|
import {
|
||||||
CarouselLayout,
|
CarouselLayout,
|
||||||
@ -11,7 +12,9 @@ import {
|
|||||||
RoomAudioRenderer,
|
RoomAudioRenderer,
|
||||||
useCreateLayoutContext,
|
useCreateLayoutContext,
|
||||||
usePinnedTracks,
|
usePinnedTracks,
|
||||||
|
useRoomInfo,
|
||||||
useTracks,
|
useTracks,
|
||||||
|
useParticipants,
|
||||||
} from '@livekit/components-react';
|
} from '@livekit/components-react';
|
||||||
import { RoomEvent, Track } from 'livekit-client';
|
import { RoomEvent, Track } from 'livekit-client';
|
||||||
import { useEffect, useRef } from 'react';
|
import { useEffect, useRef } from 'react';
|
||||||
@ -20,6 +23,10 @@ import ChatRoom from '../ChatRoom/ChatRoom';
|
|||||||
export default function LiveRoom() {
|
export default function LiveRoom() {
|
||||||
const lastAutoFocusedScreenShareTrack = useRef(null);
|
const lastAutoFocusedScreenShareTrack = useRef(null);
|
||||||
|
|
||||||
|
// get livekit identity
|
||||||
|
const room = useRoomInfo();
|
||||||
|
const participants = useParticipants();
|
||||||
|
|
||||||
const tracks = useTracks(
|
const tracks = useTracks(
|
||||||
[
|
[
|
||||||
{ source: Track.Source.Camera, withPlaceholder: true },
|
{ source: Track.Source.Camera, withPlaceholder: true },
|
||||||
@ -69,6 +76,14 @@ export default function LiveRoom() {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<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>
|
||||||
|
</header>
|
||||||
<div className="lk-video-conference">
|
<div className="lk-video-conference">
|
||||||
<LayoutContextProvider value={layoutContext}>
|
<LayoutContextProvider value={layoutContext}>
|
||||||
<div className="lk-video-conference-inner">
|
<div className="lk-video-conference-inner">
|
||||||
@ -95,5 +110,6 @@ export default function LiveRoom() {
|
|||||||
<RoomAudioRenderer />
|
<RoomAudioRenderer />
|
||||||
<ConnectionStateToast />
|
<ConnectionStateToast />
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,67 +1,32 @@
|
|||||||
.main {
|
.wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.videoWrapper {
|
.header {
|
||||||
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 {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 80px;
|
width: 100%;
|
||||||
border-top: 1px solid var(--border-color);
|
height: 48px;
|
||||||
box-sizing: border-box;
|
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
& > button {
|
.title {
|
||||||
background-color: var(--background-color-secondary);
|
padding: 0 16px;
|
||||||
color: var(--text-color-primary);
|
font-size: 14px;
|
||||||
border: none;
|
line-height: 1.4;
|
||||||
border-radius: 4px;
|
font-weight: 500;
|
||||||
padding: 8px 16px;
|
}
|
||||||
cursor: pointer;
|
|
||||||
transition: background-color 0.2s;
|
|
||||||
|
|
||||||
&:hover {
|
.roomInfo {
|
||||||
background-color: var(--background-color-tertiary);
|
display: flex;
|
||||||
}
|
align-items: center;
|
||||||
}
|
gap: 4px;
|
||||||
|
padding: 0 16px;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.4;
|
||||||
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import instance from '../../utils/axios/instance';
|
|||||||
import { API_URL, ROOM_URL } from '../../constants';
|
import { API_URL, ROOM_URL } from '../../constants';
|
||||||
import useBoundStore from '../../store';
|
import useBoundStore from '../../store';
|
||||||
import '@livekit/components-styles';
|
import '@livekit/components-styles';
|
||||||
|
import LoadingIndicator from '../../components/LoadingIndicator.jsx/LoadingIndicator';
|
||||||
|
|
||||||
export default function LivePage() {
|
export default function LivePage() {
|
||||||
const { roomId } = useParams();
|
const { roomId } = useParams();
|
||||||
@ -26,8 +27,7 @@ export default function LivePage() {
|
|||||||
}
|
}
|
||||||
}, [generateToken, liveToken]);
|
}, [generateToken, liveToken]);
|
||||||
|
|
||||||
return (
|
return liveToken ? (
|
||||||
liveToken && (
|
|
||||||
<LiveKitRoom
|
<LiveKitRoom
|
||||||
token={liveToken}
|
token={liveToken}
|
||||||
serverUrl={ROOM_URL}
|
serverUrl={ROOM_URL}
|
||||||
@ -36,6 +36,7 @@ export default function LivePage() {
|
|||||||
>
|
>
|
||||||
<LiveRoom />
|
<LiveRoom />
|
||||||
</LiveKitRoom>
|
</LiveKitRoom>
|
||||||
)
|
) : (
|
||||||
|
<LoadingIndicator fill />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
export const liveSlice = (set) => ({
|
export const liveSlice = (set) => ({
|
||||||
liveToken: null,
|
liveToken: null,
|
||||||
setLiveToken: (liveToken) => set({ liveToken }),
|
setLiveToken: (liveToken) => set({ liveToken }),
|
||||||
|
participants: 0,
|
||||||
|
setParticipants: (participants) => set({ participants }),
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user