反应聊天应用程序中的已读和未读消息状态

时间:2019-04-24 09:50:04

标签: node.js reactjs mongodb websocket

我正在开发React Chat应用程序,并且希望显示“已发送”消息的状态,如果用户已看到消息,则希望将消息状态更新为“已读”。但是问题是,更新状态没有显示在另一个浏览器选项卡/窗口中。

import React, { Component } from 'react'
import { withRouter, Redirect } from "react-router-dom";
import { connect } from 'react-redux';
import ChatInput from './ChatInput'
import ChatMessage from './ChatMessage'
import Sidebar from './Sidebar'
import Header from './Header'
import $ from 'jquery'

const URL = 'ws://localhost:3030'

class Chat extends Component {
  constructor(props) {
    super();
    this.state = {
      name: props.loginData.username?props.loginData.username:sessionStorage.getItem("userName"),
      toUserName: props.loginData.toUser,
      messages: [],
      userdata: [],
      receiveUser:"",
      readmsg:false,
      updateMsg:false
    }
    this.refreshMessages = this.refreshMessages.bind(this)
  }

  ws = new WebSocket(URL)

  componentDidMount() {

    this.ws.onopen = () => {

      // On connecting, do nothing but log it to the console
    }

    this.ws.onmessage = () => {

      // On receiving a message, add it to the list of messages
      // alert("new message received")
      const userchat = {
        userId: sessionStorage.getItem("userId"),
        chatId: sessionStorage.getItem("chatId")
      }
      fetch('/getmessages', {
        method: 'POST',
        body: JSON.stringify(userchat),
        headers: {
          'Content-Type': 'application/json',
          'Accept': 'application/json'
        }
      })
        .then((response) => response.json())
        .then((data) => {
          this.setState({
            userdata: data
          })
        })
        .catch((error) => {
          console.log("Error, with message::", error)
        });
    }

    this.ws.onclose = () => {

      // Automatically try to reconnect on connection loss
      this.setState({
        ws: new WebSocket(URL),
      })
    }
  }

  componentWillReceiveProps(newprops) {
    this.setState({
      toUserName: newprops.loginData.toUser
    })
  }

  addMessage = message =>{
    this.setState(state => ({ messages: [message, ...state.messages] 
    })
  )}

  submitMessage = messageString => {
    $(".chat-room").animate({ scrollTop: $(document).height() }, "fast");
    // on submitting the ChatInput form, send the message, add it to the list and reset the input
    const message = {
      name: this.state.name,
      message: messageString,
      toUser: this.state.toUserName,
      userId: sessionStorage.getItem("userId"),
      chatId: sessionStorage.getItem("chatId")
    }
    this.ws.send(JSON.stringify(message))

    //api call using fetch
    fetch('/chat', {
      method: 'POST',
      body: JSON.stringify(message),
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json'
      }
    })
      .then((response) => response.json())
      .then((data) => {
        this.refreshMessages()
      })
      .catch((error) => {
        console.log("Error, with message::", error)
      });
  }

  refreshMessages() {
    const userchat = {
      userId: sessionStorage.getItem("userId"),
      chatId: sessionStorage.getItem("chatId")
    }
    fetch('/getmessages', {
      method: 'POST',
      body: JSON.stringify(userchat),
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json'
      }
    })
      .then((response) => response.json())
      .then((data) => {
        this.setState({
          userdata: data,
          readmsg:false
        })
      })
      .catch((error) => {
        console.log("Error, with message::", error)
      });
  }

  onSendUserChat(msgData) {
    this.setState({
      userdata: msgData
    },()=>{    
      setTimeout( () => {
        this.setState({
        readmsg: true
      });
    }, 2000);
    })
  }

  receiveUserName(name){
    this.setState({
      receiveUser:name
    })
  }

  render() {
    if (sessionStorage.getItem("userName") != null) {
    return (
      <div>
        <Header name={this.state.name} id={sessionStorage.getItem("userId")} sendUserName={this.receiveUserName.bind(this)} />
        <div id="chatContainer" >
          <Sidebar sendUserchat={this.onSendUserChat.bind(this)} receiveUser={this.state.receiveUser} updateMsg={this.state.updateMsg} />
            <section id="main">
            <div className="chat-room" id="main-chat">
            {
              this.state.userdata.map((msg, index) => {
                return (
                  <p> <strong>{msg.userName}:&nbsp;</strong> <em> {msg.message}</em><div className="read-msg">{msg.read===false?"sent":"read"}</div></p>
              />
                )
              })
            }
            </div>
            <ChatInput
              ws={this.ws}
              onSubmitMessage={messageString => this.submitMessage(messageString)}
            />
          </section>          
        </div>
      </div>
    )
   }
   else{
    return <Redirect to="/" />;
   }
  }
}

// Connect redux state
export default withRouter(connect((state) => ({ loginData: state.chat.loginData }))(Chat));

如何在有关聊天应用程序的窗口或浏览器选项卡中更新状态值。

谢谢。

1 个答案:

答案 0 :(得分:0)

状态是特定会话的本地内容。每个会话都有其自己的状态。

您要实现的目标只能从“第一次”会话发送到服务器。

在下一个会话中从服务器检索,并在第二个会话中更改状态。