upd
This commit is contained in:
+21
-13
@@ -9,6 +9,7 @@ import useStreamUserStore from "../stores/useStreamUserStore";
|
||||
import { FormEvent, useEffect, useRef, useState } from "react";
|
||||
import useSocketStore from "../stores/useSocketStore";
|
||||
import useChatStore from "../stores/useChatStore";
|
||||
import { isMobile } from "react-device-detect";
|
||||
|
||||
interface Props {
|
||||
onClose: () => void;
|
||||
@@ -26,6 +27,8 @@ function Chat2({ onClose }: Props) {
|
||||
function sendMessage(e: FormEvent) {
|
||||
e.preventDefault();
|
||||
|
||||
if (!messageText || messageText === " ") return;
|
||||
|
||||
socket?.emit("message", messageText);
|
||||
|
||||
setMessageText("");
|
||||
@@ -42,22 +45,24 @@ function Chat2({ onClose }: Props) {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`chat relative h-[calc(100vh-48px)] flex flex-col w-[296px] bg-white`}
|
||||
className={`chat lg:relative absolute right-0 lg:h-[calc(100dvh-48px)] h-dvh flex flex-col w-[296px] bg-white border-t border-[#DAE0E5]`}
|
||||
>
|
||||
<div className="flex items-center justify-between p-2 pl-4 border-b border-[#DAE0E5]">
|
||||
<p className="text-sm font-semibold">
|
||||
<Trans i18nKey={"chat"}>Чат</Trans>
|
||||
</p>
|
||||
<Button
|
||||
variant="tertiary"
|
||||
icon={<CloseIcon />}
|
||||
onlyIcon
|
||||
onClick={onClose}
|
||||
/>
|
||||
<div className="p-4 pb-2">
|
||||
<div className="flex items-center justify-between border-b border-[#DAE0E5] pb-4">
|
||||
<p className="text-sm font-semibold">
|
||||
<Trans i18nKey={"chat"}>Чат демонстрации</Trans>
|
||||
</p>
|
||||
<Button
|
||||
variant="tertiary"
|
||||
icon={<CloseIcon />}
|
||||
onlyIcon
|
||||
onClick={onClose}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
ref={messagesRef}
|
||||
className="flex-1 overflow-y-scroll flex flex-col gap-1 p-3 border-b border-[#DAE0E5]"
|
||||
className="flex-1 overflow-y-scroll flex flex-col gap-1 px-4 pb-2 pt-0 border-b border-[#DAE0E5]"
|
||||
>
|
||||
{messages.map((message, index) => (
|
||||
<div
|
||||
@@ -85,12 +90,15 @@ function Chat2({ onClose }: Props) {
|
||||
<div className="p-3 pl-4">
|
||||
<form onSubmit={sendMessage} className="flex items-center gap-3">
|
||||
<input
|
||||
autoFocus={isMobile ? false : true}
|
||||
ref={messageTextRef}
|
||||
type="text"
|
||||
placeholder={t("writeAMessage")}
|
||||
className="w-full text-sm bg-transparent outline-none"
|
||||
value={messageText}
|
||||
onChange={(e) => setMessageText(e.target.value)}
|
||||
onChange={(e) =>
|
||||
setMessageText(e.target.value.replace(/\s+/g, " "))
|
||||
}
|
||||
/>
|
||||
<button type="submit" className="text-[#49A1F5] outline-none">
|
||||
<SendChatIcon />
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import CloseIcon from "./icons/CloseIcon";
|
||||
import HandOffIcon from "./icons/HandOffIcon";
|
||||
// import MicroOnIcon from "./icons/MicroOnIcon";
|
||||
|
||||
interface Props {
|
||||
handleToggleControl: () => void;
|
||||
handleKick: () => void;
|
||||
}
|
||||
|
||||
function Dropdown({ handleToggleControl, handleKick }: Props) {
|
||||
return (
|
||||
<div className="absolute py-2 mt-4 space-y-1 bg-white rounded-lg shadow w-60">
|
||||
{/* <button className="flex items-center gap-2 px-4 py-1 text-sm">
|
||||
<span className="text-[#77828C]">
|
||||
<MicroOnIcon />
|
||||
</span>
|
||||
<span>Отключить микрофон</span>
|
||||
</button> */}
|
||||
<button
|
||||
className="flex items-center gap-2 px-4 py-1 text-sm"
|
||||
onClick={handleToggleControl}
|
||||
>
|
||||
<span className="text-[#77828C]">
|
||||
<HandOffIcon />
|
||||
</span>
|
||||
<span>Передать управление</span>
|
||||
</button>
|
||||
<button
|
||||
className="flex items-center gap-2 px-4 py-1 text-sm"
|
||||
onClick={handleKick}
|
||||
>
|
||||
<span className="text-[#EB5757]">
|
||||
<CloseIcon />
|
||||
</span>
|
||||
<span>Исключить</span>
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Dropdown;
|
||||
+69
-65
@@ -1,82 +1,86 @@
|
||||
import { useRef, useState } from "react";
|
||||
import CloseIcon from "./icons/CloseIcon";
|
||||
import { isMobile } from "react-device-detect";
|
||||
import DesktopIcon from "./icons/DesktopIcon";
|
||||
import HandOnIcon from "./icons/HandOnIcon";
|
||||
import Button from "./ui/Button";
|
||||
import MobileIcon from "./icons/MobileIcon";
|
||||
import MoreIcon from "./icons/MoreIcon";
|
||||
import { useOnClickOutside } from "usehooks-ts";
|
||||
import Tooltip from "./Tooltip";
|
||||
import Button from "./ui/Button";
|
||||
import IUser from "../types/IUser";
|
||||
import CloseIcon from "./icons/CloseIcon";
|
||||
import { useState } from "react";
|
||||
import { useClickAway } from "@uidotdev/usehooks";
|
||||
|
||||
interface UserProps {
|
||||
interface Props {
|
||||
me: IUser;
|
||||
user: IUser;
|
||||
onTransferControl: (userId: string) => void;
|
||||
onKickUser: (userId: string) => void;
|
||||
className?: string;
|
||||
tooltip?: boolean;
|
||||
handleTransferControl: () => void;
|
||||
handleKick: () => void;
|
||||
}
|
||||
|
||||
function User({
|
||||
user,
|
||||
onTransferControl,
|
||||
onKickUser,
|
||||
className,
|
||||
tooltip = false,
|
||||
}: UserProps) {
|
||||
const [isShowMore, setIsShowMore] = useState(false);
|
||||
const moreRef = useRef(null);
|
||||
function User({ me, user, handleTransferControl, handleKick }: Props) {
|
||||
const [showMore, setShowMore] = useState(false);
|
||||
|
||||
function handleClickOutside() {
|
||||
setIsShowMore(false);
|
||||
}
|
||||
|
||||
useOnClickOutside(moreRef, handleClickOutside);
|
||||
|
||||
function handleClickTransferControl() {
|
||||
onTransferControl(user.id);
|
||||
setIsShowMore(false);
|
||||
}
|
||||
|
||||
function handleClickKickUser() {
|
||||
onKickUser(user.id);
|
||||
setIsShowMore(false);
|
||||
}
|
||||
const ref = useClickAway<HTMLDivElement>(() => {
|
||||
setShowMore(false);
|
||||
});
|
||||
|
||||
return (
|
||||
<div ref={moreRef} className="relative">
|
||||
<Button
|
||||
variant="tertiary"
|
||||
icon={<MoreIcon />}
|
||||
onlyIcon
|
||||
onClick={() => setIsShowMore((prev) => !prev)}
|
||||
className="group relative"
|
||||
>
|
||||
{tooltip && <Tooltip text="Действия" />}
|
||||
</Button>
|
||||
<div key={user.id} className="flex items-center gap-2">
|
||||
<div className="relative w-6 h-6 bg-[#E6ECF2] rounded-full flex items-center justify-center">
|
||||
<p className="text-xs font-semibold">{user.name[0]?.toUpperCase()}</p>
|
||||
{user?.isControlAllowed && (
|
||||
<div className="absolute bottom-0 right-0 bg-[#49A1F5] w-2 h-2 rounded-full border border-white"></div>
|
||||
)}
|
||||
</div>
|
||||
<p className="text-xs">{user.name}</p>
|
||||
<div className="text-[#CCCCCC]">
|
||||
{isMobile ? <MobileIcon /> : <DesktopIcon />}
|
||||
</div>
|
||||
|
||||
{isShowMore && (
|
||||
<div
|
||||
className={`absolute top-[calc(100%+18px)] bg-white rounded-lg py-2 z-10 shadow ${className}`}
|
||||
>
|
||||
<button
|
||||
className="flex items-center gap-2 px-4 py-1 hover:bg-[#E6ECF2] transition-colors w-full"
|
||||
onClick={handleClickTransferControl}
|
||||
>
|
||||
{me.isAdmin && (
|
||||
<div ref={ref} className="relative z-10">
|
||||
<Button
|
||||
variant="tertiary"
|
||||
icon={<MoreIcon />}
|
||||
onlyIcon
|
||||
onClick={() => setShowMore(true)}
|
||||
/>
|
||||
<Tooltip text={"Действия"} />
|
||||
|
||||
{showMore && (
|
||||
<div className="absolute py-2 mt-4 space-y-1 bg-white rounded-lg shadow w-60">
|
||||
{/* <button className="flex items-center gap-2 px-4 py-1 text-sm hover:bg-[#E6ECF2] transition-colors">
|
||||
<span className="text-[#77828C]">
|
||||
<HandOnIcon />
|
||||
<MicroOnIcon />
|
||||
</span>
|
||||
<span className="text-sm whitespace-nowrap">
|
||||
Передать управление
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
className="flex items-center gap-2 px-4 py-1 hover:bg-[#E6ECF2] transition-colors w-full"
|
||||
onClick={handleClickKickUser}
|
||||
>
|
||||
<span className="text-[#EB5757]">
|
||||
<CloseIcon />
|
||||
</span>
|
||||
<span className="text-sm">Исключить</span>
|
||||
</button>
|
||||
<span>Отключить микрофон</span>
|
||||
</button> */}
|
||||
<button
|
||||
className="flex items-center w-full gap-2 px-4 py-1 text-sm hover:bg-[#E6ECF2] transition-colors"
|
||||
onClick={() => {
|
||||
handleTransferControl();
|
||||
setShowMore(false);
|
||||
}}
|
||||
>
|
||||
<span className="text-[#77828C]">
|
||||
<HandOnIcon />
|
||||
</span>
|
||||
<span>Передать управление</span>
|
||||
</button>
|
||||
<button
|
||||
className="flex items-center w-full gap-2 px-4 py-1 text-sm hover:bg-[#E6ECF2] transition-colors"
|
||||
onClick={() => {
|
||||
handleKick();
|
||||
setShowMore(false);
|
||||
}}
|
||||
>
|
||||
<span className="text-[#EB5757]">
|
||||
<CloseIcon />
|
||||
</span>
|
||||
<span>Исключить</span>
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user