feat: video call

This commit is contained in:
Tristan Yang
2023-04-23 09:56:05 +08:00
parent 824f85b5a8
commit 9f0b419f43
6 changed files with 107 additions and 54 deletions
+28 -16
View File
@@ -8,6 +8,9 @@ import IconMicOff from '../../assets/icons/mic.off.svg';
import IconCallOff from '../../assets/icons/headphone.svg';
import IconSoundOn from '../../assets/icons/sound.on.svg';
import IconSoundOff from '../../assets/icons/sound.off.svg';
import IconCameraOff from '../../assets/icons/camera.off.svg';
import IconCamera from '../../assets/icons/camera.svg';
import IconScreen from '../../assets/icons/share.screen.svg';
import { useVoice } from '../../common/component/Voice';
import Signal from '../../common/component/Signal';
import Tooltip from '../../common/component/Tooltip';
@@ -19,7 +22,7 @@ type Props = {
const RTCWidget = ({ id, context = "channel" }: Props) => {
const { t } = useTranslation("chat");
const { leave, voicingInfo, setMute, setDeafen, joining = true } = useVoice({ context, id });
const { leave, voicingInfo, setMute, setDeafen, joining = true, openCamera } = useVoice({ context, id });
const { loginUser, channelData, userData } = useAppSelector(store => {
return {
userData: store.users.byId,
@@ -28,25 +31,36 @@ const RTCWidget = ({ id, context = "channel" }: Props) => {
};
});
if (!loginUser || !voicingInfo || joining) return null;
const name = voicingInfo.context == "channel" ? channelData[voicingInfo.id]?.name : userData[voicingInfo.id]?.name;
if (!name) return null;
// const name = voicingInfo.context == "channel" ? channelData[voicingInfo.id]?.name : userData[voicingInfo.id]?.name;
// if (!name) return null;
const isReConnecting = voicingInfo.connectionState == "RECONNECTING";
return (
<div className='bg-gray-100 dark:bg-gray-900 flex flex-col p-2 rounded-3xl m-3 mb-4 text-sm'>
{/* {voicingInfo && */}
<div className="flex justify-between items-center border-b border-b-gray-200 dark:border-b-gray-800 pb-2">
<div className="flex flex-1 items-center gap-1">
<Signal strength={voicingInfo.downlinkNetworkQuality} />
<div className="flex flex-col">
<span className={clsx('text-green-800 font-bold', isReConnecting && `text-red-500`)}>{isReConnecting ? `Voice Reconnecting...` : `Voice Connected`}</span>
<span className='text-gray-600 dark:text-gray-400 text-xs truncate max-w-[170px]' >{voicingInfo.context == "channel" ? "Channel" : "DM"} / {voicingInfo.context == "channel" ? channelData[voicingInfo.id].name : userData[voicingInfo.id].name}</span>
<div className="border-b border-b-gray-200 dark:border-b-gray-800 pb-2">
<div className="flex justify-between items-center">
<div className="flex flex-1 items-center gap-1">
<Signal strength={voicingInfo.downlinkNetworkQuality} />
<div className="flex flex-col">
<span className={clsx('text-green-800 font-bold', isReConnecting && `text-red-500`)}>{isReConnecting ? `Voice Reconnecting...` : `Voice Connected`}</span>
<span className='text-gray-600 dark:text-gray-400 text-xs truncate max-w-[170px]' >{voicingInfo.context == "channel" ? "Channel" : "DM"} / {voicingInfo.context == "channel" ? channelData[voicingInfo.id].name : userData[voicingInfo.id].name}</span>
</div>
</div>
<Tooltip tip={t("leave_voice")} placement="top">
<IconCallOff onClick={leave} role="button" className="fill-red-600" />
</Tooltip>
</div>
<div className="flex items-center gap-2 mt-3">
<button onClick={openCamera} className='rounded-lg py-2 px-5 bg-white/50 dark:bg-black/50 flex items-center gap-1'>
<IconCameraOff className="fill-gray-800 dark:fill-gray-200 w-6 h-6" />
<span className='text-sm text-gray-800 dark:text-gray-200 font-semibold'>Video</span>
</button>
<button className='rounded-lg py-2 px-5 bg-white/50 dark:bg-black/50 flex items-center gap-1'>
<IconScreen className="fill-gray-800 dark:fill-gray-200 w-6 h-6" />
<span className='text-sm text-gray-800 dark:text-gray-200 font-semibold'>Screen</span>
</button>
</div>
<Tooltip tip={t("leave_voice")} placement="top">
<IconCallOff onClick={leave} role="button" className="fill-red-600" />
</Tooltip>
</div>
{/* } */}
<div className="flex justify-between items-center pt-2">
<div className="flex items-center gap-3">
<User uid={loginUser.uid} compact />
@@ -55,7 +69,6 @@ const RTCWidget = ({ id, context = "channel" }: Props) => {
<span className='text-gray-400 text-xs'>#{loginUser.uid}</span>
</div>
</div>
{/* {voicingInfo && */}
<div className="flex gap-2 px-1">
<Tooltip tip={voicingInfo.deafen ? t("undeafen") : t("deafen")} placement="top">
{voicingInfo.deafen ? <IconSoundOff role="button" onClick={setDeafen.bind(null, false)} /> : <IconSoundOn role="button" onClick={setDeafen.bind(null, true)} />}
@@ -67,7 +80,6 @@ const RTCWidget = ({ id, context = "channel" }: Props) => {
<IconMic onClick={setMute.bind(null, true)} role="button" />}
</Tooltip>
</div>
{/* } */}
</div>
</div>
);