sheva77 3 роки тому
батько
коміт
5b2d195a41

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

@@ -3,6 +3,7 @@
 import { urlConst } from "../const";
 import { actionPromise } from "../Reducers";
 import { actionMsgNewChat, actionMsgInsertInHead } from "../Actions";
+import { store } from "../Reducers";
 
 const getGQL = (url) => (query, variables = {}) => {
     return fetch(url, {
@@ -19,7 +20,7 @@ const getGQL = (url) => (query, variables = {}) => {
 export const gql = getGQL(urlConst);
 
 const toQuery = (str, fields = ["title", "text"]) => {
-    str = str.replace(/ +/g, " ").trim();
+    str = str.replace(/ +/g, " ").trim(); // "/ +/g" - оставляет только по одному пробелу в последовательностях пробелов
     str = "/" + str.split(" ").join("|") + "/";
 
     let arr = fields.map((s) => {
@@ -135,3 +136,57 @@ export const actionSearchChat = (_userId = "", str = "") => async (dispatch) =>
     );
     console.log("actionSearchChat - searchData:", searchData);
 };
+
+export const actionUserFind = (skip = 0) => async (dispatch) => {
+    let users = await dispatch(
+        actionPromise(
+            "UserFind",
+            gql(
+                `query UserFind($query:String){
+                    UserFind(query:$query){
+                        _id
+                        login
+                        nick
+                        avatar{url}
+                    }
+                }`,
+                { query: JSON.stringify([{}, { sort: [{ _id: -1 }], skip: [skip], limit: [100] }]) }
+            )
+        )
+    );
+    // console.log("actionUserCount - userCount:", userCount);
+    if (!users.errors) {
+        users = users.data;
+        // console.log("actionUserFind - UserFind:", users);
+    }
+};
+
+export const actionUsersConcat = (userArr) => {
+    // console.log("actionUsersConcat - ", JSON.stringify(userArr, null, 4));
+    // console.log("actionUsersConcat - ", userArr);
+    return { type: "NEW_USER_PART", userArr };
+};
+
+export const actionGetAllUsers = () => async (dispatch) => {
+    let userCount = await dispatch(
+        actionPromise(
+            "userCount",
+            gql(
+                `query UsersCount{
+                    UserCount(query:"[{}]")
+                }`
+            )
+        )
+    );
+    // console.log("actionUserCount - userCount:", userCount.data.UserCount);
+    if (!userCount.errors) {
+        userCount = userCount.data.UserCount;
+        // console.log("actionUserCount - userCount:", userCount);
+
+        for (let i = 0; i < userCount; i += 100) {
+            // console.log("++++++++", i);
+            await actionUserFind(i)(dispatch);
+            dispatch(actionUsersConcat(store.getState().promise.UserFind.payload.data.UserFind));
+        }
+    }
+};

+ 4 - 0
chat_final_bootstrap/src/Actions/ActionsUser.js

@@ -0,0 +1,4 @@
+export const actionUser = (msgArr) => {
+    // console.log("actionMsgAdd - ", JSON.stringify(msgArr, null, 4));
+    return { type: "NEW_CHAT", msgs: { [msgArr[0].chat._id]: msgArr } };
+};

+ 8 - 1
chat_final_bootstrap/src/Actions/index.js

@@ -1,5 +1,11 @@
 import { actionAuthLogin, actionAuthLogout, actionLogin, actionRegistration, actionUserInfo } from "./ActionLogin";
-import { gql, actionSearchMessagesByChatId, actionGetMessagesByChatId, actionSearchChat } from "./ActionsGql";
+import {
+    gql,
+    actionSearchMessagesByChatId,
+    actionGetMessagesByChatId,
+    actionSearchChat,
+    actionGetAllUsers,
+} from "./ActionsGql";
 import { actionMsgNewChat, actionCurChatId, actionMsgInsertInHead } from "./ActionsMsg";
 
 export {
@@ -15,4 +21,5 @@ export {
     actionMsgNewChat,
     actionCurChatId,
     actionMsgInsertInHead,
+    actionGetAllUsers,
 };

+ 6 - 1
chat_final_bootstrap/src/App.scss

@@ -15,7 +15,7 @@ $position-values: (
 
 div {
     border-radius: 7px;
-    border: 1px solid red;
+    // border: 1px solid red;
 }
 
 ::-webkit-scrollbar {
@@ -58,6 +58,11 @@ body {
     }
 }
 
+.allUsersList {
+    max-height: calc(100vh - 180px);
+    overflow: auto;
+}
+
 .avatarka {
     > img,
     > div {

+ 2 - 7
chat_final_bootstrap/src/Components/ChatsList.js

@@ -1,6 +1,6 @@
 import logo from "../images//logo23.jpg";
 import { connect } from "react-redux";
-import { urlConst } from "../const";
+import { urlUploadConst } from "../const";
 import { Link } from "react-router-dom";
 import { Counter } from "../Components";
 import personFillIcon from "../icons/person-fill.svg";
@@ -26,12 +26,9 @@ const ChatItem = ({ _id = "", avatar, title, messages, userId, currentChatId })
                     }
                 >
                     <div className="d-flex justify-content-start align-items-center">
-
-
-
                         <div className="avatarka ">
                             {avatar && avatar.url ? (
-                                <img src={`${urlConst}/${avatar.url}`}></img>
+                                <img src={`${urlUploadConst}/${avatar.url}`}></img>
                             ) : (
                                 <div className="d-flex justify-content-center align-items-center bg-success border border-2 border-success gradient">
                                     <div className="fs-5 text-light fw-bolder">
@@ -47,8 +44,6 @@ const ChatItem = ({ _id = "", avatar, title, messages, userId, currentChatId })
                             )}
                         </div>
 
-                        
-
                         <div className="text-dark fs-5 fw-bolder ms-2">{`${title}`}</div>
                     </div>
                     <span className="position-absolute bottom-0 end-0  badge rounded-pill bg-secondary">

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

@@ -45,7 +45,7 @@ if (
     
 
     return (
-        <div className="PageMain container-fluid">
+        <div className="container-fluid">
             <div className="row g-3">
                 <div className="col-md-4">
                     <Sidebar />

+ 99 - 13
chat_final_bootstrap/src/Pages/PageNewChat.js

@@ -1,4 +1,11 @@
 import { ButtonToMain } from "../Components";
+import { urlUploadConst } from "../const";
+import { actionGetAllUsers } from "../Actions";
+import { connect } from "react-redux";
+import { useEffect } from "react";
+import { useState } from "react";
+import { store } from "../Reducers";
+import { useRef } from "react";
 
 const ChatDashBoard = () => {
     return (
@@ -41,29 +48,103 @@ const AllUsersConst = [
     },
 ];
 
-const UserItem = ({ _id, login, nick, avatar }) => {
+const UserItem = ({ _id, login, nick, avatar, myId }) => {
+    const [isSelected, setIsSelected] = useState(false);
     const avatarUrl = avatar && avatar.url;
+    nick = !!nick ? nick : login;
+
+    const doSelectUser = () => {
+        setIsSelected((prev) => !prev);
+    };
+
     return (
-        <p>
-            <div>{_id}</div>
-            <div>{login}</div>
-            <div>{nick}</div>
-            <div>{avatarUrl}</div>
-        </p>
+        <>
+            <li
+                className={`list-group-item list-group-item-${
+                    isSelected || _id === myId ? "success" : "light"
+                } m-1 gradient shadow-sm border-2 `}
+                onClick={doSelectUser}
+            >
+                <div className="d-flex justify-content-start align-items-center">
+                    <div className="avatarka ">
+                        {avatarUrl ? (
+                            <img
+                                src={`${urlUploadConst}/${avatarUrl}`}
+                                className="border border-2 border-success"
+                            ></img>
+                        ) : (
+                            <div className="d-flex justify-content-center align-items-center bg-success border border-2 border-success gradient">
+                                <div className="fs-5 text-light fw-bolder">
+                                    {!!nick &&
+                                        `${
+                                            nick.split(" ")[0] &&
+                                            nick.split(" ")[0][0] &&
+                                            nick.split(" ")[0][0].toUpperCase()
+                                        }` +
+                                            `${
+                                                (nick.split(" ").slice(1).pop() &&
+                                                    nick.split(" ").slice(1).pop()[0] &&
+                                                    nick.split(" ").slice(1).pop()[0].toUpperCase()) ||
+                                                ""
+                                            }`}
+                                </div>
+                            </div>
+                        )}
+                    </div>
+                    <div className="text-dark fs-5  ms-2">{`${nick}`}</div>
+                </div>
+                <span className="position-absolute bottom-0 end-0  badge rounded-pill bg-secondary">
+                    {_id}
+                    <span className="visually-hidden">всего сообщений</span>
+                </span>
+            </li>
+        </>
     );
 };
 
-const AllUsers = ({ allUsersArray = AllUsersConst, getAllUsers = null }) => {
-    console.log(allUsersArray);
+const AllUsers = ({ allUsersArray = [], getAllUsers = null, myId }) => {
+    const [users, setUsers] = useState([]);
+
+    useEffect(() => {
+        if (typeof getAllUsers === "function") getAllUsers();
+    }, []);
+
+    useEffect(() => {
+        setUsers(
+            allUsersArray
+                .filter((el) => {
+                    if (!el.login) return false;
+                    if (el.nick && !el.nick.replace(/ +/g, " ").trim()) {
+                        return false;
+                    } else {
+                        return !!el.login.replace(/ +/g, " ").trim();
+                    }
+                })
+                .sort((a, b) => ((a.nick || a.login) > (b.nick || b.login) ? 1 : -1))
+        );
+        // выкидываем пользователей, у которых (ник из одних пробелов) или (нет ника но логин из одних пробелов)
+        // console.log("+++++++++++++++++", users, allUsersArray);
+    }, [allUsersArray]);
+
     return (
-        <>
+        <div className="bg-light">
             <h4>AllUsers</h4>
-            <div>{!!allUsersArray && allUsersArray.map((user) => <UserItem key={user._id} {...user} />)}</div>
-        </>
+            <ul className="list-group allUsersList" role="tablist">
+                {!!users && users.map((user) => <UserItem key={user._id} {...user} myId={myId} />)}
+            </ul>
+        </div>
     );
 };
 
+const CAllUsers = connect((s) => ({ allUsersArray: s.allUsers, myId: s.auth.payloadId }), {
+    getAllUsers: actionGetAllUsers,
+})(AllUsers);
+
 export const PageNewChat = () => {
+    useEffect(() => {
+        store.dispatch({ type: "CLEAR_USERS" });
+    }, []);
+
     return (
         <>
             PageNewChat
@@ -71,7 +152,12 @@ export const PageNewChat = () => {
             <div className="PageMain container-fluid">
                 <div className="row g-3">
                     <div className="col-md-4">
-                        <AllUsers />
+                        <input
+                            className="form-control mb-2 p-2 border border-success border-2"
+                            placeholder="Search user by nick/login/_id"
+                            onInput={(e) => {}}
+                        ></input>
+                        <CAllUsers />
                     </div>
                     <div className="col-md-8">
                         <ChatDashBoard />

+ 20 - 5
chat_final_bootstrap/src/Reducers/index.js

@@ -56,9 +56,7 @@ function authReducer(state, action) {
 }
 
 function msgReduser(state = {}, action) {
-    // console.log("------------", action);
-
-    if (["LOGOUT", "LOGIN"].includes(action.type)) return {}; // кликнули по новому чату в sideBar
+    if (["LOGOUT", "LOGIN"].includes(action.type)) return {};
 
     if (action.type === "NEW_CHAT") {
         return { ...state, ...action.msgs };
@@ -73,10 +71,21 @@ function msgReduser(state = {}, action) {
 }
 
 function currentChatIdReduser(state = {}, action) {
-    if (["LOGOUT", "LOGIN"].includes(action.type)) return {}; // кликнули по новому чату в sideBar
+    if (["LOGOUT", "LOGIN"].includes(action.type)) return {};
+
     if (action.type === "CURRENTID") {
         return { curChatId: action.curChatId };
     }
+
+    return state;
+}
+
+function allUsersReduser(state = [], action) {
+    if (["LOGOUT", "LOGIN", "CLEAR_USERS"].includes(action.type)) return [];
+    if (action.type === "NEW_USER_PART") {
+        return state.concat(action.userArr);
+    }
+
     return state;
 }
 
@@ -117,7 +126,13 @@ export const actionPromise = (name, promise) => {
 };
 
 export const store = createStore(
-    combineReducers({ auth: authReducer, promise: promiseReducer, msg: msgReduser, curChatId: currentChatIdReduser }),
+    combineReducers({
+        auth: authReducer,
+        promise: promiseReducer,
+        msg: msgReduser,
+        curChatId: currentChatIdReduser,
+        allUsers: allUsersReduser,
+    }),
     applyMiddleware(thunk)
 );