enhance: polish voice

This commit is contained in:
Tristan Yang
2023-05-05 15:58:43 +08:00
parent d7472f3947
commit 2d0123e204
5 changed files with 30 additions and 14 deletions
+5
View File
@@ -309,3 +309,8 @@ svg:focus {
border: none;
outline: none;
}
/* camera video object-fit */
[id^="CAMERA_"] video {
object-fit: cover !important;
}
+9 -3
View File
@@ -3,7 +3,7 @@ import { memo, useEffect } from 'react';
import { useDispatch } from 'react-redux';
import { useGetAgoraChannelsQuery, useGetAgoraStatusQuery, useGenerateAgoraTokenMutation } from '../../app/services/server';
import { updateChannelVisibleAside } from '../../app/slices/footprint';
import { addVoiceMember, removeVoiceMember, updateConnectionState, updateDeafenStatus, updateMuteStatus, updateVoicingInfo, updateVoicingMember, updateVoicingNetworkQuality, upsertVoiceList } from '../../app/slices/voice';
import { addVoiceMember, removeVoiceMember, updateConnectionState, updateDeafenStatus, updateMuteStatus, updatePin, updateVoicingInfo, updateVoicingMember, updateVoicingNetworkQuality, upsertVoiceList } from '../../app/slices/voice';
import { useAppSelector } from '../../app/store';
import AudioJoin from '../../assets/join.wav';
import { playAgoraVideo } from '../utils';
@@ -202,6 +202,8 @@ const useVoice = ({ id, context = "channel" }: VoiceProps) => {
};
const openCamera = async () => {
const localVideoTrack = await AgoraRTC.createCameraVideoTrack();
// 取消正在进行的桌面共享
await stopShareScreen();
await window.VOICE_CLIENT?.publish(localVideoTrack);
dispatch(updateVoicingInfo({
video: true,
@@ -253,7 +255,7 @@ const useVoice = ({ id, context = "channel" }: VoiceProps) => {
const startShareScreen = async () => {
try {
const localVideoTrack = await AgoraRTC.createScreenVideoTrack({
electronScreenSourceId: "share_screen",
// electronScreenSourceId: "share_screen",
selfBrowserSurface: "exclude",
// 配置屏幕共享编码参数,详情请查看 API 文档。
encoderConfig: "1080p_1",
@@ -273,6 +275,11 @@ const useVoice = ({ id, context = "channel" }: VoiceProps) => {
// 放到全局变量里
window.VIDEO_TRACK_MAP[loginUid] = localVideoTrack;
playAgoraVideo(loginUid);
// 进入全屏并Pin自己
if (context == "channel") {
dispatch(updateChannelVisibleAside({ id, aside: "voice_fullscreen" }));
dispatch(updatePin({ uid: loginUid, action: "pin" }));
}
// 监听屏幕共享结束事件
if ("close" in localVideoTrack) {
localVideoTrack.getMediaStreamTrack().onended = () => {
@@ -281,7 +288,6 @@ const useVoice = ({ id, context = "channel" }: VoiceProps) => {
}
} catch (error) {
console.log("start share screen error", error);
}
};
+1 -1
View File
@@ -120,7 +120,7 @@ const Layout: FC<Props> = ({
{aside}
</div>}
{users && <div className="hidden md:block">{users}</div>}
{voice && <div className="absolute right-11 top-14 h-fit overflow-y-scroll bg-white dark:!bg-gray-700 md:block">{voice}</div>}
{voice && <div className="max-md:absolute max-md:right-11 max-md:top-14 max-md:h-fit max-md:overflow-y-scroll bg-white dark:!bg-gray-700 md:block">{voice}</div>}
{!readonly && inputMode == "text" && isActive && (
<DnDTip context={context} name={name} />
)}
@@ -106,8 +106,13 @@ const VoiceManagement = ({ id, context, info, setMute, leave, closeCamera, openC
{muted ? <IconMicOff className="w-4 fill-gray-500 dark:fill-gray-400" /> : <IconMic className="w-4 fill-gray-500 dark:fill-gray-400" />}
</div>
</div>
<div onDoubleClick={handleFullscreen.bind(null, uid)} id={`CAMERA_${uid}`} className="w-[98%] rounded overflow-hidden m-auto">
{/* camera placeholder */}
<div className="overflow-hidden group rounded relative" onDoubleClick={handleFullscreen.bind(null, uid)}>
<div id={`CAMERA_${uid}`} className="w-[98%] m-auto">
{/* camera placeholder */}
</div>
<button onClick={handleFullscreen.bind(null, uid)} className="invisible group-hover:visible w-5 h-5 p-1 bg-black/40 top-1 right-1.5 absolute rounded">
<IconFullscreen className="w-full h-full fill-white" />
</button>
</div>
</li>;
})}
@@ -127,7 +132,7 @@ const VoiceManagement = ({ id, context, info, setMute, leave, closeCamera, openC
</Tooltip>
<Tooltip tip={"Share Screen"} placement="top">
<li role={"button"} onClick={shareScreen ? stopShareScreen : startShareScreen} className={clsx("py-2 px-3 rounded ", shareScreen ? "bg-green-700" : "bg-gray-100 dark:bg-gray-900")}>
<IconScreen className="fill-gray-700 dark:fill-gray-300" />
<IconScreen className={clsx("dark:fill-gray-300", shareScreen ? "fill-gray-200" : "fill-gray-800")} />
</li>
</Tooltip>
<Tooltip tip={"Fullscreen"} placement="top">
+7 -7
View File
@@ -84,7 +84,7 @@ const VoiceFullscreen = ({ id, context }: Props) => {
<div className="px-7 py-6 flex justify-between">
<span className='text-sm font-semibold'>{_name}</span>
<div className="flex gap-4">
<IconExitScreen role="button" onClick={handleExitFullscreen} className="fill-gray-300" />
<IconExitScreen role="button" onClick={handleExitFullscreen} className="fill-gray-200" />
</div>
</div>
{/* middle */}
@@ -111,15 +111,15 @@ const VoiceFullscreen = ({ id, context }: Props) => {
{shareScreen ? <div className={clsx("w-1 h-1 absolute z-40 rounded-full bg-green-700/60", special ? "top-2 left-2" : "top-1 left-1 px-2")} /> : null}
{!disablePin &&
<Tooltip tip={"Remove pin"} disabled={!special} placement="right">
<button data-uid={uid} data-action={special ? "unpin" : "pin"} role={"button"} onClick={handlePin} className={clsx("absolute left-1 top-1 z-40 p-1 rounded bg-black/50", special ? "" : "invisible group-hover:visible")}>
{special ? <IconPin className="w-3 h-3 fill-gray-300" /> : <IconPin className="w-3 h-3 fill-gray-300" />}
<button data-uid={uid} data-action={special ? "unpin" : "pin"} role={"button"} onClick={handlePin} className={clsx("absolute left-1 top-1 z-40 p-1 rounded bg-black/50", special ? "px-2 py-0.5" : "invisible group-hover:visible")}>
{special ? <IconPin className={clsx("fill-gray-200", special ? "w-4" : "w-3")} /> : <IconPin className={clsx("fill-gray-200", special ? "w-4" : "w-3")} />}
</button>
</Tooltip>}
<span className={clsx("text-gray-300 bg-black/50 rounded-lg absolute z-40", special ? "left-2 bottom-2 px-2 py-1 text-sm " : "left-1 bottom-1 p-1 text-xs")} title={curr?.name}>
{curr?.name}
</span>
<div className={clsx("flex items-center gap-2 absolute z-40 rounded bg-black/50", special ? "bottom-2 right-2 px-2 py-0.5" : "bottom-1 right-1 px-2")}>
{muted ? <IconMicOff className={clsx("fill-gray-300", special ? "w-4" : "w-3")} /> : <IconMic className={clsx(" fill-gray-300 ", special ? "w-4" : "w-3")} />}
{muted ? <IconMicOff className={clsx("fill-gray-200", special ? "w-4" : "w-3")} /> : <IconMic className={clsx("fill-gray-200 ", special ? "w-4" : "w-3")} />}
</div>
<div id={`CAMERA_${uid}`} className={clsx("absolute top-0 left-0 z-30 w-full h-full overflow-hidden m-auto", special ? "" : "rounded")}>
{/* camera placeholder */}
@@ -132,17 +132,17 @@ const VoiceFullscreen = ({ id, context }: Props) => {
<ul className='py-4 flex justify-center gap-2'>
<Tooltip tip={muted ? t("unmute") : t("mute")} placement="top">
<li role={"button"} onClick={setMute.bind(null, !muted)} className="flex-center py-1 px-3 rounded bg-gray-100 dark:bg-gray-900">
{muted ? <IconMicOff className="fill-gray-700 dark:fill-gray-300" /> : <IconMic className="fill-gray-700 dark:fill-gray-300" />}
{muted ? <IconMicOff className="fill-gray-700 dark:fill-gray-200" /> : <IconMic className="fill-gray-700 dark:fill-gray-200" />}
</li>
</Tooltip>
<Tooltip tip={video ? t("camera_off") : t("camera_on")} placement="top">
<li role={"button"} onClick={video ? closeCamera : openCamera} className="flex-center py-1 px-3 rounded bg-gray-100 dark:bg-gray-900">
{video ? <IconCamera className="fill-gray-700 dark:fill-gray-300" /> : <IconCameraOff className="fill-gray-700 dark:fill-gray-300" />}
{video ? <IconCamera className="fill-gray-700 dark:fill-gray-200" /> : <IconCameraOff className="fill-gray-700 dark:fill-gray-200" />}
</li>
</Tooltip>
<Tooltip tip={"Share Screen"} placement="top">
<li role={"button"} onClick={shareScreen ? stopShareScreen : startShareScreen} className={clsx("flex-center py-1 px-3 rounded ", shareScreen ? "bg-green-700" : "bg-gray-100 dark:bg-gray-900")}>
<IconScreen className={clsx("dark:fill-gray-300 w-6 h-6", shareScreen ? "fill-gray-300" : "fill-gray-700")} />
<IconScreen className={clsx("dark:fill-gray-200 w-6 h-6", shareScreen ? "fill-gray-200" : "fill-gray-700")} />
</li>
</Tooltip>
<StyledButton onClick={leave} className='bg-red-600 hover:!bg-red-700 text-center'>