Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

Rev 3055 | Autoría | Ultima modificación | Ver Log |

import React, { useCallback } from "react";
import { useState, useEffect } from "react";
import { axios } from "../../utils";
import Contacts from "./contacts/Contacts";
import NotificationAlert from "../../shared/notification/NotificationAlert";
import Groups from "./groups/Groups";
import PersonalChat from "./personal-chat/PersonalChat";
import { FiMaximize2 } from 'react-icons/fi'

const notifyAudio = new Audio("/audio/chat.mp3");

const Chat = (props) => {
  // states
  const [fullChats, setFullChats] = useState([]);
  const [contacts, setContacts] = useState([]);
  const [groups, setGroups] = useState([]);
  const [activeChats, setActiveChats] = useState([]);
  const [isChatOpen, setIsChatOpen] = useState(false);
  const [isMuted, setIsMuted] = useState(false);
  const [activeTab, setActiveTab] = useState("user");
  const [search, setSearch] = useState('');
  const [loading, setLoading] = useState(false);

  const filtredContacts = contacts.filter(({ name }) => name.toLowerCase().includes(search.toLowerCase()))
  const filtredGroups = groups.filter(({ name }) => name.toLowerCase().includes(search.toLowerCase()))

  const handleEntities = entities => {
    setFullChats([...entities]);
    let newUserContacts = [];
    let newGroups = [];
    entities.map((entity) => {
      if (entity.not_received_messages) {
        handleNewMessage(entity);
      }
      switch (entity.type) {
        case "user":
          newUserContacts = [...newUserContacts, entity];
          handleUpdateOnline(entity);
          break;
        case "group":
          newGroups = [...newGroups, entity];
          break;
        default:
          break;
      }
    });
    setContacts(newUserContacts);
    setGroups(newGroups);
  }

  useEffect(() => {
    axios.get("/chat/heart-beat")
      .then(({ data }) => {
        if (data.success) {
          const entities = data.data

          entities.map(entity => {
            if (entity.is_open !== 0) {
              handleOpenConversation(entity, false);
            }
          })
        }
      })
  }, [])

  const heartBeat = async () => {
    try {
      const res = await axios.get("/chat/heart-beat")
      let entities = [];
      const resData = res.data;
      if (resData.success) {
        entities = resData.data;
        handleEntities(entities)
      }
      return entities;
    } catch (error) {
      console.log('>>: chat error > ', error)
    }
  };


  const handleUpdateOnline = (entity) => {
    const existingChatId = activeChats.findIndex(
      (activeChat) => activeChat.id === entity.id
    );
    if (existingChatId >= 0) {
      if (activeChats[existingChatId].online !== entity.online) {
        const newActiveChats = [...activeChats];
        newActiveChats[existingChatId].online = entity.online;
        setActiveChats(newActiveChats);
      }
    }
  };

  const handleNewMessage = async (unseeEntity) => {
    await axios.post(unseeEntity.url_mark_received).then((response) => {
      ('')
    });
    if (!activeChats.some((activeChat) => activeChat.id === unseeEntity.id)) {
      setActiveChats([...activeChats, { ...unseeEntity, minimized: false }]);
      playNotifyAudio();
    } else {
      const existingChatId = activeChats.findIndex(
        (activeChat) => activeChat.id === unseeEntity.id
      );
      if (!activeChats[existingChatId].unsee_messages) {
        const newActiveChats = [...activeChats];
        newActiveChats[existingChatId].unsee_messages = true;
        setActiveChats(newActiveChats);
        playNotifyAudio(newActiveChats[existingChatId].minimized);
      }
    }
  };

  const handleOpenConversation = (entity, minimized = false) => {
    if (activeChats.length < 3 && !activeChats.some((el) => el.id === entity.id)) {
      setActiveChats([...activeChats, { ...entity, minimized: minimized }]);
    }
    if (activeChats.length >= 3 && !activeChats.some((el) => el.id === entity.id)) {
      activeChats.map((el, index) => {
        if (index === 0) {
          axios.post(el.url_close)
        }
      })
      const newActiveChats = activeChats.filter((el, index) => index !== 0)
      setActiveChats([...newActiveChats, { ...entity, minimized: minimized }]);
    }
  };

  const handleReadChat = async (index) => {
    const newActiveChats = [...activeChats];
    if (activeChats[index].not_seen_messages) {
      const seen = await axios.post(activeChats[index].url_mark_seen);
      if (seen.data.success) {
        newActiveChats[index].not_seen_messages = false;
      }
    }
    if (activeChats[index].not_received_messages) {
      const seen = await axios.post(activeChats[index].url_mark_received);
      if (seen.data.success) {
        newActiveChats[index].not_received_messages = false;
      }
    }
    if (activeChats !== newActiveChats)
      setActiveChats(newActiveChats);
  };

  const handleMinimizeChat = (chatIndex, minimize) => {
    const newActiveChats = [...activeChats];
    switch (minimize) {
      case false:
        newActiveChats[chatIndex].minimized = false;
        break;
      default:
        newActiveChats[chatIndex].minimized =
          !newActiveChats[chatIndex].minimized;
        break;
    }
    setActiveChats(newActiveChats);
  };

  const handleCloseChat = (entityId, url_close) => {
    let newActiveChats = [];
    setLoading(true)
    axios.post(url_close).then((response) => {
      const resData = response.data;
    });
    newActiveChats = activeChats.filter(
      (activeChat) => activeChat.id !== entityId
    );
    setActiveChats(newActiveChats);
    setLoading(false)
  };

  const playNotifyAudio = (minimized = true) => {
    if (!isMuted && minimized) {
      notifyAudio.play();
    }
  };

  const handleMute = () => {
    setIsMuted(!isMuted);
    if (isMuted) {
      notifyAudio.play();
    }
  };

  const handleChangeTab = (tab) => {
    setActiveTab(tab);
  };

  useEffect(() => {
    if (!loading) {
      const fetchData = async () => {
        setLoading(true)
        const entities = await heartBeat() || [];
        setLoading(false)

        return entities
      }

      setTimeout(() => {
        fetchData()
      }, "2000")
    }
  }, [loading]);

  useEffect(() => {
    emojione.imageType = "png";
    emojione.sprites = false;
    emojione.ascii = true;
    emojione.imagePathPNG = props.emojiOnePath;
  }, []);

  return (window.innerWidth > 1000 && window.location.pathname !== '/chat') ? (
    <React.Fragment>
      <div id="drupalchat-wrapper">
        <div id="drupalchat">
          <div className="item-list" id="chatbox_chatlist">
            <ul id="mainpanel">
              <li id="chatpanel" className="first last">
                <div className="subpanel">
                  <div
                    className="subpanel_title"
                    onClick={(e) => (e.currentTarget === e.target) && setIsChatOpen(!isChatOpen)}
                  >
                    <a
                      href="/chat"
                      className="text-gray text-chat-title"
                    >
                      Chat
                      <FiMaximize2 className="ml-3" />
                    </a>
                    <div className="subpanel_title-icons">
                      <i
                        className={`icon ${isMuted ? "icon-volume-off" : "icon-volume-2"} text-20`}
                        onClick={handleMute}
                      />
                      <i
                        className={`fa ${isChatOpen ? "fa-angle-down" : "fa-angle-up"} text-20`}
                        onClick={() => setIsChatOpen(!isChatOpen)}
                      />
                    </div>
                  </div>
                  <div
                    id="showhidechatlist"
                    style={{ display: isChatOpen ? "grid" : "none" }}
                  >
                    <div
                      className="drupalchat_search_main chatboxinput"
                      style={{ background: "#f9f9f9" }}
                    >
                      <input
                        className="drupalchat_searchinput live-search-box"
                        id="live-search-box"
                        type="text"
                        name='search'
                        value={search}
                        onChange={e => setSearch(e.target.value || '')}
                      />
                      <i className="searchbutton fas fa-search" />
                    </div>
                    <div
                      className="drupalchat_search_main chatboxinput"
                      style={{ background: "#f9f9f9" }}
                    >
                      <button
                        className={`${activeTab === 'user' ? 'active' : ''}`}
                        onClick={() => handleChangeTab("user")}
                      >
                        Contactos
                      </button>
                      <button
                        className={`${activeTab === 'group' ? 'active' : ''}`}
                        onClick={() => handleChangeTab("group")}
                      >
                        Grupos
                      </button>
                    </div>
                    <div
                      className="contact-list chatboxcontent"
                      style={{
                        display: activeTab === "user" ? "block" : "none",
                      }}
                    >
                      <Contacts
                        contacts={filtredContacts}
                        onOpenConversation={handleOpenConversation}
                      />
                    </div>
                    <div
                      className="group-list chatboxcontent"
                      style={{
                        display: activeTab === "group" ? "block" : "none",
                      }}
                    >
                      <ul id="group-list-ul" className="live-search-list-group">
                        <Groups
                          groups={filtredGroups}
                          onOpenConversation={handleOpenConversation}
                        />
                      </ul>
                    </div>
                    <div
                      className="group-contacts-list chatboxcontent"
                      style={{ display: "none" }}
                    >
                      <div style={{ textAlign: "center", fontSize: "13px" }}>
                        Integrantes del grupo
                      </div>
                      <ul
                        id="contact-group-list-ul"
                        className="live-search-list"
                      ></ul>
                    </div>
                  </div>
                </div>
              </li>
            </ul>
          </div>
        </div>
      </div>
      <div style={{ display: "flex" }}>
        {activeChats.map((entity, index) => (
          <PersonalChat
            key={entity.id}
            entity={entity}
            index={index}
            onClose={handleCloseChat}
            onMinimize={handleMinimizeChat}
            onRead={handleReadChat}
          />
        ))}
      </div>
      <NotificationAlert />
    </React.Fragment>
  ) : (
    ""
  );
};

export default Chat;