<!doctype html> <html lang="ru"> <head> <meta charset="UTF-8"> <title>My Chat</title> <link rel="stylesheet" type="text/css" href="dist/bundle.css"> </head> <body> <div id="app"></div> <script src="dist/bundle.js"></script> </body> </html>
import React from 'react'; import UserList from './../components/userList' import History from './../components/history' // SDK import Scorocode from './../scorocode.min' // SDK Scorocode.Init({ ApplicationID: '<appId>', WebSocketKey: '<websocketKey>', JavaScriptKey: '<javascriptKey>' }); var WS = new Scorocode.WebSocket('scorochat'); class AppView extends React.Component{ constructor () { super(); this.state = { userList: {}, user: { id: '', name: '' }, history: [] }; } guid () { function s4() { return Math.floor((1 + Math.random()) * 0x10000) .toString(16) .substring(1); } return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4(); } onOpen () { setInterval(() => { this.getUserList(); }, 10000); this.getUserList (); } onError (err) {} onClose () {} updateUserList (user) { let now = new Date().getTime(); let userList = this.state.userList; if (!userList[user.id]) { userList[user.id] = { name: user.name }; } userList[user.id].expire = now; for (let id in userList) { if (now - userList[id].expire > 10000) { delete userList[id]; } } this.setState({ userList: userList }); } getUserList () { var data = JSON.stringify({ cmd: 'getUserList', from: this.state.user, text: '' }); WS.send(data); } onMessage (data) { var result = JSON.parse(data); switch (result.cmd) { case 'message': let history = this.state.history.slice(); history.push(result); this.setState({history: history}); break; case 'getUserList': WS.send(JSON.stringify({ cmd: 'userList', from: this.state.user, text: '' })); break; case 'userList': this.updateUserList(result.from); break } } send (msg) { var data = JSON.stringify({ cmd: 'message', from: this.state.user, text: msg }); WS.send(data); } keyPressHandle(ev) { let value = ev.target.value; if (ev.charCode === 13 && !ev.shiftKey) { ev.preventDefault(); if (!ev.target.value) { return; } this.send(value); ev.target.value = ''; } } componentWillMount () { let userName = prompt(' ?'); userName = (userName || 'New User').substr(0, 30); this.setState({ user: { name: userName, id: this.guid() } }); } componentDidMount () { // WS.on("open", this.onOpen.bind(this)); WS.on("close", this.onClose.bind(this)); WS.on("error", this.onError.bind(this)); WS.on("message", this.onMessage.bind(this)); } render () { return ( <div className="viewport"> <div className="header"> <h1>ScoroChat</h1> </div> <div className="main"> <div className="left_panel"> <UserList userList={this.state.userList}/> </div> <div className="content"> <div className="history"> <History history={this.state.history} /> </div> <div className="control"> <div className="container"> <textarea placeholder=" " onKeyPress={this.keyPressHandle.bind(this)}></textarea> </div> </div> </div> </div> </div> ) } } export default AppView;
import React from "react"; var avatar = require('./../../img/avatar.png'); export default class UserList extends React.Component{ constructor(props){ super(props); } render () { const historyIds = Object.keys(this.props.userList); return ( <div id="members"> {historyIds.map((id) => { return ( <div className='userList' key={id}> <div className='userList_avatar'> <img src=http://{avatar} /> </div> <div className='userList_info'> <span>{this.props.userList[id].name}</span> </div> </div> ) })} </div> ) } }
import React from 'react' var avatar = require('./../../img/avatar.png'); class History extends React.Component { constructor(props) { super(props); } getDate () { let dt = new Date(); return ('0' + dt.getHours()).slice(-2) + ':' + ('0' + dt.getMinutes()).slice(-2) + ' ' + ('0' + dt.getDate()).slice(-2) + '.' + ('0' + (dt.getMonth() + 1)).slice(-2) + '.' + dt.getFullYear(); } render () { return ( <div id="msgContainer" className="container"> {this.props.history.map((item, ind) => { return ( <div className="msg_container" key={ind}> <div className="avatar"> <img src=http://{avatar} /> </div> <div className="msg_content"> <div className="title"> <a className="author" href="javascript:void(0)">{item.from.name}</a> <span>{this.getDate()}</span> </div> <div className="msg_body"> <p>{item.text}</p> </div> </div> </div> ) })} </div> ); } componentDidUpdate() { var historyContainer = document.getElementsByClassName('history')[0]; var msgContainer = document.getElementById('msgContainer'); // if (msgContainer.offsetHeight - (historyContainer.scrollTop + historyContainer.offsetHeight) < 200) { historyContainer.scrollTop = msgContainer.offsetHeight - historyContainer.offsetHeight; } } } export default History;
Source: https://habr.com/ru/post/308068/
All Articles