sheva77 %!s(int64=3) %!d(string=hai) anos
pai
achega
93e552ec6f

+ 1 - 0
chat_final_bootstrap/src/Actions/ActionsGql.js

@@ -48,6 +48,7 @@ export const actionSearchMessagesByChatId = (_chatId, str) => async (dispatch) =
                             _id
                             login
                             nick
+                            avatar{url}
                         }
                         text
                         createdAt

+ 60 - 4
chat_final_bootstrap/src/App.scss

@@ -1,6 +1,38 @@
+//
+
+$position-values: (
+    right: 17%,
+    20: 20%,
+);
+
+div {
+    border-radius: 7px;
+    // border: 1px solid red;
+}
+
+::-webkit-scrollbar {
+    width: 7px; /* width of the entire scrollbar */
+    background-color: #d1e7dd;
+}
+
+::-webkit-scrollbar-track {
+    box-shadow: 5px 5px 5px -5px rgba(11, 61, 6, 0.2) inset;
+    -webkit-box-shadow: 5px 5px 5px -5px rgba(11, 61, 6, 0.2) inset;
+    background-color: #d1e7dd;
+}
+
+::-webkit-scrollbar-thumb {
+    border-radius: 10px;
+    // background: linear-gradient(#d1e7dd, #198754, #198754, #198754, #d1e7dd);
+    background: linear-gradient(#d1e7dd, #198754 20%, #198754 80%, #d1e7dd);
+}
+
 body {
     overflow: hidden;
 }
+.header {
+    min-width: 360px;
+}
 
 .ChatsList {
     max-height: calc(100vh - 350px);
@@ -13,7 +45,8 @@ body {
         border-radius: 50%;
         overflow: hidden;
         float: left;
-        i {
+        i,
+        p {
             color: honeydew;
             margin: 0;
             position: absolute;
@@ -52,9 +85,30 @@ body {
     }
 }
 
-div {
-    border-radius: 7px;
-    // border: 1px solid red;
+.messagesTitle {
+    min-height: 70px;
+    div:first-child {
+        position: relative;
+        width: 48px;
+        height: 48px;
+        border-radius: 50%;
+        overflow: hidden;
+        float: left;
+        i,
+        p {
+            color: honeydew;
+            margin: 0;
+            position: absolute;
+            top: 50%;
+            left: 50%;
+            margin-right: -50%;
+            transform: translate(-52%, -55%);
+        }
+    }
+}
+
+.messageItem {
+    width: 80%;
 }
 
 .LoginForm {
@@ -85,3 +139,5 @@ div {
         border-radius: 50%;
     }
 }
+
+@import "/node_modules/bootstrap/scss/bootstrap";

+ 2 - 2
chat_final_bootstrap/src/Components/AdditionalTools.js

@@ -19,10 +19,10 @@ export const AdditionalTools = ({ _userId, onSearch = null }) => {
     }, [searchStr]);
 
     return (
-        <div className="bg-light mb-2">
+        <div className="bg-light mb-2 text-nowrap">
             <input
                 className="form-control mb-2 p-2 border border-success border-2"
-                placeholder="Serch by title in my chats"
+                placeholder="Search by title in my chats"
                 onInput={(e) => {
                     setSearchStr(e.target.value);
                 }}

+ 72 - 13
chat_final_bootstrap/src/Components/ChatContain.js

@@ -4,10 +4,18 @@ import { useState, useEffect, useRef } from "react";
 import logo from "../images//logo23.jpg";
 import { actionSearchMessagesByChatId } from "../Actions";
 import ScrollableFeed from "react-scrollable-feed";
-
 import { urlConst } from "../const";
 
-const MessageItem = ({ _id, createdAt = 0, text = "", owner: { login = "", nick = "" } }) => {
+const MessageItem = ({
+    _id,
+    createdAt = 0,
+    text = "",
+    owner: { _id: ownerId, login = "", nick = "", avatar },
+    myId,
+}) => {
+    // первый _id - messageId
+
+    if (!nick) nick = login;
     let date = new Date(+createdAt);
     let dateStr =
         date.getFullYear().toString().padStart(4, 0) +
@@ -21,32 +29,65 @@ const MessageItem = ({ _id, createdAt = 0, text = "", owner: { login = "", nick
         date.getMinutes().toString().padStart(2, 0);
     // ":" +
     // date.getSeconds().toString().padStart(2, 0);
+
     return (
-        <div>
+        // <div className="list-group-item list-group-item-success m-2 gradient shadow-sm border-2">
+        <div
+            className={`messageItem list-group-item m-2 gradient shadow-sm border-2 ${
+                myId === ownerId
+                    ? "start-right list-group-item-success text-success"
+                    : " list-group-item-light text-red"
+            }`}
+        >
+            {/*  */}
+            {avatar && avatar.url ? (
+                <img src={`${urlConst}/${avatar.url}`}></img>
+            ) : (
+                <div className="bg-success border border-2 border-success gradient">
+                    {/* <i class="fs-3 text-light bi bi-chat-dots "></i> */}
+                    <p className="fs-5 text-light fw-bolder">
+                        {`${title.split(" ")[0][0].toUpperCase()}` +
+                            `${
+                                (title.split(" ").slice(1).pop() && title.split(" ").slice(1).pop()[0].toUpperCase()) ||
+                                ""
+                            }`}
+                    </p>
+                </div>
+            )}
+
+            {/*  */}
+            {/* <span>{`myid: ${myId}`}</span> */}
             <span>{`message id: ${_id}`}</span>
             <br />
-            <p>{`Login: ${login}, Nick: ${nick}`}</p>
+            <p>{`Login: ${login}, Nick: ${nick}, ownerId: ${ownerId}`}</p>
             <h5>{text}</h5>
             <div>{dateStr}</div>
         </div>
     );
 };
 
-const MessagesList = ({ arrayOfMessages }) => {
+const MessagesList = ({ arrayOfMessages, myId }) => {
     const messagesEndRef = useRef(null);
 
+    //FIXME: подмена myId
+    if (myId) myId = "5e97105693e2915e617c6fc1";
+
+    // скролл в самый низ при приходе новых сообщений
     const scrollToBottom = () => messagesEndRef.current.scrollIntoView({ behavior: "smooth" });
 
     useEffect(scrollToBottom, [arrayOfMessages]);
 
     return (
         <div className="Messages_map">
-            {!!arrayOfMessages && arrayOfMessages.map((mess) => <MessageItem key={mess._id} {...mess} />)}
+            {/* //FIXME: */}
+            {/* {myId} */}
+            {!!arrayOfMessages && arrayOfMessages.map((mess) => <MessageItem key={mess._id} {...mess} myId={myId} />)}
             <div ref={messagesEndRef} />
         </div>
     );
 };
 
+// скролл вниз при новых сообщениях только если мы ща уже внизу
 // const MessagesList = ({ arrayOfMessages }) => {
 //     return (
 //         <div className="Messages_map">
@@ -64,11 +105,12 @@ const CMessagesList = connect(
             s.promise.MessageFind.payload &&
             s.promise.MessageFind.payload.data &&
             s.promise.MessageFind.payload.data.MessageFind,
+        myId: s.auth && s.auth.payloadId,
     }),
     {}
 )(MessagesList);
 
-const Messages = ({ arrayOfMessages, avatar, _id = "", title = "", doSearchMsg }) => {
+const Messages = ({ arrayOfMessages, avatar, _id = "", title = "No Title", doSearchMsg }) => {
     // id чата, аватар чата
 
     const [searchMsgStr, setSearchMsgStr] = useState("");
@@ -84,16 +126,33 @@ const Messages = ({ arrayOfMessages, avatar, _id = "", title = "", doSearchMsg }
     return (
         <div className="Messages">
             <input
-                placeholder="Serch message"
+                placeholder="Search message"
                 onInput={(e) => setSearchMsgStr(e.target.value)}
                 className="form-control mb-2 p-2 border border-success border-2"
             ></input>
-            <span>🔍</span>
-            <div>
-                <b>ChatContain</b>
+            {/* <span>🔍</span> */}
+            <div className=" messagesTitle mb-3 border border-3 border-success p-2">
+                {/* <img src={avatar && avatar.url ? urlConst + "/" + avatar.url : logo}></img> */}
+
+                {avatar && avatar.url ? (
+                    <img src={`${urlConst}/${avatar.url}`}></img>
+                ) : (
+                    <div className="bg-success border border-2 border-success gradient">
+                        {/* <i class="fs-3 text-light bi bi-chat-dots "></i> */}
+                        <p className="fs-5 text-light fw-bolder">
+                            {title &&
+                                `${title.split(" ")[0][0].toUpperCase()}` +
+                                    `${
+                                        (title.split(" ").slice(1).pop() &&
+                                            title.split(" ").slice(1).pop()[0].toUpperCase()) ||
+                                        ""
+                                    }`}
+                        </p>
+                    </div>
+                )}
+
+                <span className="ms-2 fs-4 fw-bolder">{`Title: ${title}`}</span>
                 {` _chatId: ${_id}`}
-                <img src={avatar && avatar.url ? urlConst + "/" + avatar.url : logo}></img>
-                <span>{`Title: ${title}`}</span>
             </div>
             <div>
                 <CMessagesList />

+ 20 - 13
chat_final_bootstrap/src/Components/ChatsList.js

@@ -5,40 +5,47 @@ import { Link } from "react-router-dom";
 import personFillIcon from "../icons/person-fill.svg";
 import history from "../history";
 
-const ChatItem = ({ _id = "", avatar, title = "no title", messages, userId, chatId }) => (
-    // здесь _id - чата
+const ChatItem = ({ _id = "", avatar, title = "no title", messages, userId, currentChatId }) => (
+    // здесь _id - чата, currentChatId - текущий выбраный чат
     <Link to={`/main/${userId}/${_id}`} className="noUnderLine">
         <>
             <li
                 className={
-                    _id === chatId
-                        ? "list-group-item list-group-item-success my-1 gradient"
-                        : "list-group-item list-group-item-light my-1 gradient"
+                    _id === currentChatId
+                        ? "list-group-item list-group-item-success m-1 gradient shadow border-2"
+                        : "list-group-item list-group-item-light m-1 gradient shadow-sm border-2"
                 }
             >
                 <div>
                     {avatar && avatar.url ? (
                         <img src={`${urlConst}/${avatar.url}`}></img>
                     ) : (
-                        <div className="bg-success border border-2 border-success">
-                            <i class="fs-3 text-light bi bi-chat-dots "></i>
+                        <div className="bg-success border border-2 border-success gradient">
+                            {/* <i class="fs-3 text-light bi bi-chat-dots "></i> */}
+                            <p className="fs-5 text-light fw-bolder">
+                                {`${title.split(" ")[0][0].toUpperCase()}` +
+                                    `${
+                                        (title.split(" ").slice(1).pop() &&
+                                            title.split(" ").slice(1).pop()[0].toUpperCase()) ||
+                                        ""
+                                    }`}
+                            </p>
                         </div>
                     )}
                 </div>
-                <div className="text-success ">
+                <div className="text-success text-nowrap">
                     <span>Title: {title}</span>
                     <br />
                     <span>Count of msg: {messages && messages.length ? messages.length : 0}</span>
                 </div>
 
-                <br />
-                <span> chatID: {_id}</span>
+                {/* <span className="text-nowrap"> chatID: {_id}</span> */}
             </li>
         </>
     </Link>
 );
 
-const List = ({ arrayOfChats, userId, chatId }) => {
+const List = ({ arrayOfChats, userId, currentChatId }) => {
     if (!arrayOfChats) return <></>;
 
     // сортируем чаты так, чтобы сверху показывались чаты, в которых последнее сообщение "свежее" всех остальных
@@ -68,14 +75,14 @@ const List = ({ arrayOfChats, userId, chatId }) => {
     return (
         <ul class="list-group" role="tablist">
             {arrayOfChats.map((a) => (
-                <ChatItem key={a._id} {...a} userId={userId} chatId={chatId} />
+                <ChatItem key={a._id} {...a} userId={userId} currentChatId={currentChatId} />
             ))}
         </ul>
     );
 };
 
 const CList = connect((s) => ({
-    chatId:
+    currentChatId:
         s.promise.chatFindOne &&
         s.promise.chatFindOne.payload &&
         s.promise.chatFindOne.payload.data &&

+ 5 - 5
chat_final_bootstrap/src/Components/LoginInfo.js

@@ -9,14 +9,14 @@ const LoginInfo = ({ login, nick, _id, getUserInfo }) => {
     }, [_id]);
 
     return (
-        <span className="mx-2 text-white">
+        <span className="mx-2 text-white ">
             {login ? (
-                <span>
-                    {`Login: ${login}`}
+                <span className="text-nowrap">
+                    <span className="text-nowrap"> {`Login: ${login}`} </span>
                     {" / "}
-                    {`Nick: ${nick}`}
+                    <span className="text-nowrap">{`Nick: ${nick}`}</span>
                     <br />
-                    {`_id: ${_id}`}
+                    <span className="text-nowrap">{`_id: ${_id}`}</span>
                 </span>
             ) : (
                 <Link to="/">"You should log in"</Link>

+ 2 - 1
chat_final_bootstrap/src/Layout/Header.js

@@ -12,7 +12,8 @@ const CLogo = connect((s) => ({ link: s.auth.payloadId }))(Logo);
 
 export const Header = () => (
     <>
-        <Navbar className="gradient" collapseOnSelect expand="sm" bg="dark" variant="dark">
+        {/* <Navbar className="gradient" collapseOnSelect expand="sm" bg="dark" variant="dark"> */}
+        <Navbar className="gradient header" collapseOnSelect bg="dark" variant="dark">
             <Navbar.Toggle aria-controls="responsive-navbar-nav" />
             <Navbar.Collapse id="responsive-navbar-nav">
                 <Nav>

+ 1 - 1
chat_final_bootstrap/src/Layout/UserInfo.js

@@ -7,7 +7,7 @@ import { urlUploadConst } from "../const";
 export const UserInfo = ({ avatarUrl }) => (
     <div className="userInfo bg-gradient bg-success text-white p-1 py-2 mb-2 text-white">
         <Link to="/dashboard" className="userInfo noUnderLine">
-            <span className="m-2  ">
+            <span className="m-2  text-nowrap">
                 <img
                     className="border border-2 border-success bg-light"
                     src={avatarUrl ? `${urlUploadConst}/${avatarUrl}` : personFillIcon}

+ 1 - 1
chat_final_bootstrap/src/Pages/PageMain.js

@@ -41,7 +41,7 @@ const PageMain = ({match: {params: { _userId, _chatId },}, getChatList = null, g
 
     return (
         <div className="PageMain container-fluid">
-            <div className="row">
+            <div className="row g-3">
                 <div className="col-md-4">
                     {_userId + ` - подмена id`}
                     <Sidebar  />