Added Chat
This commit is contained in:
parent
090e947072
commit
37d134c81c
@ -29,7 +29,7 @@ export function CustomControlBar({ room, roomName }: CustomControlBarProps) {
|
||||
const [isRecordingRequestPending, setIsRecordingRequestPending] = useState(false);
|
||||
const [participantCount, setParticipantCount] = useState(1);
|
||||
const { dispatch } = useLayoutContext().widget;
|
||||
const { isParticipantsListOpen } = useCustomLayoutContext();
|
||||
const { isParticipantsListOpen, isChatOpen } = useCustomLayoutContext();
|
||||
const { toast } = useToast();
|
||||
const [recordingState, setRecordingState] = useState({
|
||||
recording: { isRecording: false, recorder: '' },
|
||||
@ -65,6 +65,10 @@ export function CustomControlBar({ room, roomName }: CustomControlBarProps) {
|
||||
isParticipantsListOpen.dispatch({ msg: 'toggle_participants_list' });
|
||||
}
|
||||
|
||||
const toggleChat = () => {
|
||||
if (isChatOpen.dispatch) isChatOpen.dispatch({ msg: 'toggle_chat' });
|
||||
};
|
||||
|
||||
const toggleRoomRecording = async () => {
|
||||
if (isRecordingRequestPending || (isRecording && !isSelfRecord)) return;
|
||||
setIsRecordingRequestPending(true);
|
||||
@ -149,6 +153,7 @@ export function CustomControlBar({ room, roomName }: CustomControlBarProps) {
|
||||
<div className="room-name-box">
|
||||
<span className="room-name">{roomName}</span>
|
||||
<button className="copy-link-button" onClick={handleCopyLink}>
|
||||
{' '}
|
||||
<span className="material-symbols-outlined">content_copy</span>
|
||||
</button>
|
||||
</div>
|
||||
@ -157,7 +162,9 @@ export function CustomControlBar({ room, roomName }: CustomControlBarProps) {
|
||||
<div className="control-bar control-buttons">
|
||||
<TrackToggle source={Track.Source.Microphone} />
|
||||
<TrackToggle source={Track.Source.Camera} />
|
||||
|
||||
<div className={`control-btn`} onClick={toggleChat}>
|
||||
<span className="material-symbols-outlined">chat</span>
|
||||
</div>
|
||||
<div
|
||||
className={`control-btn ${isRecording ? '' : 'disabled'} ${isRecordingRequestPending || isRecording ? 'blinking' : ''}`}
|
||||
onClick={toggleRoomRecording}
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
import React, { useState } from 'react';
|
||||
import { GridLayout, useTracks, LayoutContextProvider } from '@livekit/components-react';
|
||||
import { GridLayout, useTracks, LayoutContextProvider, Chat } from '@livekit/components-react';
|
||||
import { Track, Room } from 'livekit-client';
|
||||
import { ParticipantTile } from './ParticipantTile';
|
||||
import { CustomControlBar } from '@/app/custom/CustomControlBar';
|
||||
import { SettingsMenu } from './SettingsMenu';
|
||||
import ParticipantList from '@/app/custom/ParticipantList';
|
||||
import { CustomLayoutContextProvider } from '@/app/contexts/layout-context';
|
||||
import '../styles/Chat.css';
|
||||
|
||||
interface CustomVideoLayoutProps {
|
||||
room: Room;
|
||||
@ -13,7 +14,7 @@ interface CustomVideoLayoutProps {
|
||||
}
|
||||
|
||||
export const CustomVideoLayout: React.FC<CustomVideoLayoutProps> = ({ room, roomName }) => {
|
||||
const showChat = false;
|
||||
const [showChat, setShowChat] = useState(false);
|
||||
const [showSettings, setShowSettings] = useState(false);
|
||||
const [showParticipantsList, setShowParticipantsList] = useState(false);
|
||||
|
||||
@ -30,7 +31,17 @@ export const CustomVideoLayout: React.FC<CustomVideoLayoutProps> = ({ room, room
|
||||
layoutContextValue={{
|
||||
isParticipantsListOpen: {
|
||||
state: showParticipantsList,
|
||||
dispatch: () => setShowParticipantsList((prev) => !prev),
|
||||
dispatch: () => {
|
||||
if (showChat) setShowChat(false);
|
||||
setShowParticipantsList((prev) => !prev);
|
||||
},
|
||||
},
|
||||
isChatOpen: {
|
||||
state: showChat,
|
||||
dispatch: () => {
|
||||
if (showParticipantsList) setShowParticipantsList(false);
|
||||
setShowChat((prev) => !prev);
|
||||
},
|
||||
},
|
||||
}}
|
||||
>
|
||||
@ -50,7 +61,12 @@ export const CustomVideoLayout: React.FC<CustomVideoLayoutProps> = ({ room, room
|
||||
if ('msg' in action && action.msg === 'toggle_settings') {
|
||||
setShowSettings((prev) => !prev);
|
||||
}
|
||||
if ('msg' in action && action.msg === 'toggle_chat') {
|
||||
if (showParticipantsList) setShowParticipantsList(false);
|
||||
setShowChat((prev) => !prev);
|
||||
}
|
||||
if ('msg' in action && action.msg === 'toggle_participants_list') {
|
||||
if (showChat) setShowChat(false);
|
||||
setShowParticipantsList((prev) => !prev);
|
||||
}
|
||||
},
|
||||
@ -85,10 +101,11 @@ export const CustomVideoLayout: React.FC<CustomVideoLayoutProps> = ({ room, room
|
||||
>
|
||||
<ParticipantTile />
|
||||
</GridLayout>
|
||||
<CustomControlBar room={room} roomName={roomName} />
|
||||
<CustomControlBar room={room} roomName={roomName} />{' '}
|
||||
</div>
|
||||
</div>
|
||||
{showParticipantsList && <ParticipantList />}
|
||||
{showChat && <Chat />}
|
||||
<SettingsMenu showSettings={showSettings} />
|
||||
</div>
|
||||
</LayoutContextProvider>
|
||||
|
||||
76
styles/Chat.css
Normal file
76
styles/Chat.css
Normal file
@ -0,0 +1,76 @@
|
||||
.lk-chat {
|
||||
display: flex;
|
||||
width: 25vw;
|
||||
flex-direction: column;
|
||||
background-color: #151e27;
|
||||
margin: 1rem 1rem 4.1rem 0;
|
||||
background-color: #151e27;
|
||||
border-radius: 0.5rem;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
.lk-chat-header {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
padding: 1.25rem 1.75rem;
|
||||
height: auto;
|
||||
justify-content: start;
|
||||
align-items: center;
|
||||
font-weight: bold;
|
||||
font-size: 1.05rem;
|
||||
}
|
||||
|
||||
.lk-close-button.lk-button.lk-chat-toggle {
|
||||
color: #556171;
|
||||
cursor: pointer;
|
||||
background-color: transparent;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.lk-close-button.lk-button.lk-chat-toggle > svg {
|
||||
width: 1.3rem;
|
||||
height: 1.3rem;
|
||||
}
|
||||
|
||||
.lk-close-button.lk-button.lk-chat-toggle > svg > path {
|
||||
fill: #556171;
|
||||
}
|
||||
|
||||
.lk-close-button.lk-button.lk-chat-toggle:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.lk-list.lk-chat-messages {
|
||||
margin-bottom: auto;
|
||||
padding-inline: 1rem;
|
||||
}
|
||||
|
||||
.lk-form-control.lk-chat-form-input {
|
||||
background-color: #151e27;
|
||||
}
|
||||
|
||||
.lk-form-control.lk-chat-form-input:focus-visible {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.lk-button.lk-chat-form-button {
|
||||
background-color: #151e27;
|
||||
border: 1px solid var(--lk-border-color);
|
||||
}
|
||||
|
||||
.lk-button.lk-chat-form-button:hover {
|
||||
background-color: #212e3a;
|
||||
}
|
||||
|
||||
.lk-chat-form {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.lk-chat-entry[data-lk-message-origin='local'] .lk-message-body {
|
||||
background-color: #212e3a;
|
||||
}
|
||||
|
||||
.lk-chat-entry[data-lk-message-origin='remote'] .lk-message-body {
|
||||
background-color: #3e6189;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user