upd
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
import { format } from "date-fns";
|
||||
import { t } from "i18next";
|
||||
import { Trans } from "react-i18next";
|
||||
// import useSocketStore from "../stores/useSocketStore";
|
||||
import CloseIcon from "./icons/CloseIcon";
|
||||
import SendChatIcon from "./icons/SendChatIcon";
|
||||
import Button from "./ui/Button";
|
||||
import useStreamUserStore from "../stores/useStreamUserStore";
|
||||
import { FormEvent, useRef, useState } from "react";
|
||||
import IMessage from "../types/IMessage";
|
||||
import useStateRef from "react-usestateref";
|
||||
|
||||
interface Props {
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
function Chat2({ onClose }: Props) {
|
||||
// const { socket } = useSocketStore();
|
||||
const { me, users } = useStreamUserStore();
|
||||
const [messages] = useStateRef<IMessage[]>([]);
|
||||
const messagesRef = useRef<HTMLDivElement>(null);
|
||||
const [messageText, setMessageText] = useState<string>("");
|
||||
const messageTextRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
function sendMessage(e: FormEvent) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={`chat relative h-full flex flex-col w-[296px] bg-white`}>
|
||||
<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>
|
||||
<div
|
||||
ref={messagesRef}
|
||||
className="flex-1 overflow-y-scroll flex flex-col gap-1 p-3 border-b border-[#DAE0E5]"
|
||||
>
|
||||
{messages.map((message, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={`text-sm p-2 flex flex-col gap-1 rounded-lg ${
|
||||
users.find((user) => user.id === me?.id)?.name === message.name
|
||||
? "bg-[#C4DDF5]"
|
||||
: "bg-[#F0F1F2]"
|
||||
}`}
|
||||
>
|
||||
{users.find((user) => user.id === me?.id)?.name !==
|
||||
message.name && (
|
||||
<p className="text-[#49A1F5] font-semibold">{message.name}</p>
|
||||
)}
|
||||
|
||||
<p className="break-words">{message.text}</p>
|
||||
<p className="text-[#767676] translate-x-1 translate-y-1 self-end leading-none">
|
||||
{format(new Date(), "HH:mm")}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="p-3 pl-4">
|
||||
<form onSubmit={sendMessage} className="flex items-center gap-3">
|
||||
<input
|
||||
ref={messageTextRef}
|
||||
type="text"
|
||||
placeholder={t("writeAMessage")}
|
||||
className="w-full bg-transparent text-sm outline-none"
|
||||
value={messageText}
|
||||
onChange={(e) => setMessageText(e.target.value)}
|
||||
/>
|
||||
<button type="submit" className="text-[#49A1F5] outline-none">
|
||||
<SendChatIcon />
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Chat2;
|
||||
@@ -3,9 +3,15 @@ import useModalStore from "../stores/useModalStore";
|
||||
function ModalContainer2() {
|
||||
const { modal } = useModalStore();
|
||||
|
||||
if (modal) {
|
||||
return <div className="fixed top-0 left-0 w-full h-full">{modal}</div>;
|
||||
}
|
||||
return (
|
||||
<div
|
||||
className={`fixed top-0 left-0 w-full h-full ${
|
||||
!modal ? "hidden" : ""
|
||||
}`}
|
||||
>
|
||||
{modal}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ModalContainer2;
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
Config,
|
||||
AllSettings,
|
||||
PixelStreaming,
|
||||
} from "@epicgames-ps/lib-pixelstreamingfrontend-ue5.5";
|
||||
} from "@epicgames-ps/lib-pixelstreamingfrontend-ue5.3";
|
||||
|
||||
export interface PixelStreamingWrapperProps {
|
||||
initialSettings?: Partial<AllSettings>;
|
||||
|
||||
@@ -4,7 +4,7 @@ interface TooltipProps {
|
||||
|
||||
function Tooltip({ text }: TooltipProps) {
|
||||
return (
|
||||
<div className="group-hover:opacity-100 opacity-0 transition-opacity absolute top-[calc(100%+12px)] -left-1.5 bg-[#111C26] rounded-lg px-4 py-2 z-10 pointer-events-none whitespace-nowrap">
|
||||
<div className="absolute top-[calc(100%+12px)] -left-1.5 z-20 group-hover:opacity-100 opacity-0 transition-opacity bg-[#111C26] rounded-lg px-4 py-2 pointer-events-none whitespace-nowrap">
|
||||
<svg
|
||||
width="12"
|
||||
height="10"
|
||||
|
||||
@@ -47,7 +47,7 @@ function Video({ mediaStream, muted, user }: Props) {
|
||||
<div className="relative">
|
||||
<video
|
||||
ref={remoteVideoRef}
|
||||
className={`aspect-video w-[216px] h-[162px] rounded-lg object-cover bg-gray-500 ring-2 ${
|
||||
className={`aspect-video lg:w-[216px] w-[160px] lg:h-[162px] h-[120px] rounded-lg object-cover bg-gray-500 ring-2 ${
|
||||
!_muted && isSpeaking ? "ring-green-500" : "ring-transparent"
|
||||
}`}
|
||||
playsInline
|
||||
|
||||
@@ -31,7 +31,7 @@ function InviteModal() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="absolute top-0 lg:left-0 left-12 lg:w-full w-[calc(100vw-48px)] h-full lg:bg-black lg:bg-opacity-50 bg-white sm:border-none border-l border-[#DAE0E5] flex flex-col lg:items-center lg:justify-center">
|
||||
<div className="relative top-0 lg:left-0 left-12 lg:w-full w-[calc(100vw-48px)] h-full lg:bg-black lg:bg-opacity-50 bg-white sm:border-none border-l border-[#DAE0E5] flex flex-col lg:items-center lg:justify-center">
|
||||
<div className="bg-white flex flex-col lg:rounded-lg lg:w-[400px] lg:flex-none flex-1">
|
||||
<div className="p-2 pl-6 flex items-center justify-between border-b border-[#DAE0E5]">
|
||||
<p className="text-sm font-semibold">
|
||||
|
||||
@@ -30,7 +30,7 @@ function SetNameModal({ onAction }: Props) {
|
||||
|
||||
return (
|
||||
<div className="flex items-center justify-center w-full h-full bg-opacity-50 backdrop-blur-2xl">
|
||||
<div className="bg-white p-12 rounded-lg space-y-6">
|
||||
<div className="bg-white sm:p-12 p-6 sm:rounded-lg space-y-6 sm:h-auto h-full sm:w-auto w-full flex flex-col max-sm:justify-center">
|
||||
<p className="text-2xl font-semibold">Здравствуйте!</p>
|
||||
<div className="space-y-2">
|
||||
<p className="font-semibold">Представьтесь, пожалуйста</p>
|
||||
@@ -46,6 +46,7 @@ function SetNameModal({ onAction }: Props) {
|
||||
onChange={handleChangeName}
|
||||
autoFocus={!name}
|
||||
required
|
||||
className="max-sm:w-full"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
@@ -54,10 +55,11 @@ function SetNameModal({ onAction }: Props) {
|
||||
type="submit"
|
||||
large
|
||||
onClick={handleClickNoName}
|
||||
className="max-sm:w-full"
|
||||
>
|
||||
Не указывать
|
||||
</Button>
|
||||
<Button type="submit" large>
|
||||
<Button type="submit" large className="max-sm:w-full">
|
||||
Продолжить
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -6,6 +6,7 @@ interface InputProps {
|
||||
autoFocus?: boolean;
|
||||
required?: boolean;
|
||||
value?: string;
|
||||
className?: string;
|
||||
onChange?: (e: ChangeEvent<HTMLInputElement>) => void;
|
||||
}
|
||||
|
||||
@@ -15,13 +16,14 @@ function Input({
|
||||
autoFocus,
|
||||
required,
|
||||
value,
|
||||
className,
|
||||
onChange,
|
||||
}: InputProps) {
|
||||
return (
|
||||
<input
|
||||
type={type}
|
||||
placeholder={placeholder}
|
||||
className="bg-white border border-[#DAE0E5] w-[296px] h-10 px-2 py-2.5 rounded-lg text-sm outline-none"
|
||||
className={`bg-white border border-[#DAE0E5] w-[296px] h-10 px-2 py-2.5 rounded-lg text-sm outline-none ${className}`}
|
||||
autoFocus={autoFocus}
|
||||
required={required}
|
||||
value={value}
|
||||
|
||||
Reference in New Issue
Block a user