From 5afe18754f5676b4ecb160f8ab5fdd313bc0a908 Mon Sep 17 00:00:00 2001
From: srgooglo <38926803+srgooglo@users.noreply.github.com>
Date: Sat, 2 May 2020 19:27:45 +0200
Subject: [PATCH] update: ng-server, messaging
---
.gitignore | 1 +
config/ycore.config.js | 4 +-
globals/endpoints.js | 23 ---
globals/endpoints/comty_endpoints.js | 2 +-
package.json | 4 +-
src/@ycore/libs/comty_ng/comty_user.js | 21 ++-
src/@ycore/libs/ycore_sync/pre.js | 6 +-
src/components/Layout/Secondary/index.less | 2 +-
src/components/Layout/Secondary/renders.less | 26 +--
src/components/Layout/Sider/default.js | 2 -
src/components/Layout/Sider/default.less | 6 +-
src/pages/chats/Events.js | 11 ++
src/pages/chats/chats/ChatContainer.js | 183 +++++++++++++++++++
src/pages/chats/chats/ChatHeading.js | 18 ++
src/pages/chats/chats/SideBar.js | 80 ++++++++
src/pages/chats/index.js | 83 ++++++++-
src/pages/chats/messages/MessageInput.js | 100 ++++++++++
src/pages/chats/messages/Messages.js | 61 +++++++
src/themes/base/index.less | 8 +-
19 files changed, 583 insertions(+), 58 deletions(-)
delete mode 100755 globals/endpoints.js
create mode 100644 src/pages/chats/Events.js
create mode 100644 src/pages/chats/chats/ChatContainer.js
create mode 100644 src/pages/chats/chats/ChatHeading.js
create mode 100644 src/pages/chats/chats/SideBar.js
create mode 100644 src/pages/chats/messages/MessageInput.js
create mode 100644 src/pages/chats/messages/Messages.js
diff --git a/.gitignore b/.gitignore
index 500b786a..08f11a0e 100755
--- a/.gitignore
+++ b/.gitignore
@@ -22,3 +22,4 @@ package-lock.json
src/locales/_build
src/locales/**/*.js
android/
+direct
\ No newline at end of file
diff --git a/config/ycore.config.js b/config/ycore.config.js
index b6383eb2..47ae6307 100755
--- a/config/ycore.config.js
+++ b/config/ycore.config.js
@@ -1,5 +1,4 @@
module.exports = {
- server_endpoint: 'https://comty.julioworld.club',
siteName: 'Comty',
copyright: 'RageStudio©',
@@ -9,7 +8,8 @@ module.exports = {
DarkLogoPath: '/dark_logo.svg',
resource_bundle: 'light_ng',
- sync_server: 'http://eu653-node.ragestudio.net:5500',
+ sync_server: 'http://localhost:5500',
+ server_endpoint: 'https://comty.pw',
g_recaptcha_key: '6Lc55uUUAAAAAEIACMVf3BUzAJSNCmI3RrjEirZ6',
g_recaptcha_secret: '6Lc55uUUAAAAAOP4OgUa5DpqJC-70t53AmW0lyYf',
diff --git a/globals/endpoints.js b/globals/endpoints.js
deleted file mode 100755
index 7ddc39e1..00000000
--- a/globals/endpoints.js
+++ /dev/null
@@ -1,23 +0,0 @@
-module.exports = {
- Endpoints: {
- comments_actions: "https://api.ragestudio.net/RSA-COMTY/r/comments?access_token=",
- get_post_data: "https://api.ragestudio.net/RSA-COMTY/r/get-post-data?access_token=",
- get_user_tags: "https://api.ragestudio.net/RSA-COMTY/r/user_tags?access_token=",
- get_general_data: "https://api.ragestudio.net/RSA-COMTY/r/get-general-data?access_token=",
- follow_user: "https://api.ragestudio.net/RSA-COMTY/r/follow-user?access_token=",
- action_post: "https://api.ragestudio.net/RSA-COMTY/r/post-actions?access_token=",
- get_posts: "https://api.ragestudio.net/RSA-COMTY/r/posts?access_token=",
- find_user: "https://api.ragestudio.net/RSA-COMTY/r/find_user?access_token=",
- search_endpoint: "https://api.ragestudio.net/RSA-COMTY/r/search?access_token=",
- all_sessions: "https://api.ragestudio.net/RSA-COMTY/r/sessions?access_token=",
- get_sessions: "https://api.ragestudio.net/RSA-COMTY/r/session_id?access_token=",
- auth_endpoint: "https://api.ragestudio.net/RSA-COMTY/r/auth",
- new_post: "https://comty.julioworld.club/api/new_post?access_token=",
- get_config_endpoint: "https://api.ragestudio.net/RSA-COMTY/r/get-site-settings?access_token=",
- get_userData_endpoint: "https://api.ragestudio.net/RSA-COMTY/r/get-user-data?access_token=",
- update_userData_endpoint: "https://api.ragestudio.net/RSA-COMTY/r/update-user-data?access_token=",
- removeToken: "https://api.ragestudio.net/RSA-COMTY/r/delete-access-token?access_token=",
- register_endpoint: "https://api.ragestudio.net/RSA-COMTY/r/create-account",
- resetPassword_endpoint: "https://api.ragestudio.net/RSA-COMTY/r/send-reset-password-email?access_token=",
- }
-}
\ No newline at end of file
diff --git a/globals/endpoints/comty_endpoints.js b/globals/endpoints/comty_endpoints.js
index 45338a71..a30ab6e0 100755
--- a/globals/endpoints/comty_endpoints.js
+++ b/globals/endpoints/comty_endpoints.js
@@ -12,7 +12,7 @@ module.exports={
all_sessions: "https://api.ragestudio.net/RSA-COMTY/r/sessions?access_token=",
get_sessions: "https://api.ragestudio.net/RSA-COMTY/r/session_id?access_token=",
auth_endpoint: "https://api.ragestudio.net/RSA-COMTY/r/auth",
- new_post: "https://comty.julioworld.club/api/new_post?access_token=",
+ new_post: "https://comty.pw/api/new_post?access_token=",
get_config_endpoint: "https://api.ragestudio.net/RSA-COMTY/r/get-site-settings?access_token=",
get_userData: "https://api.ragestudio.net/RSA-COMTY/r/get-user-data?access_token=",
update_userData_endpoint: "https://api.ragestudio.net/RSA-COMTY/r/update-user-data?access_token=",
diff --git a/package.json b/package.json
index 72254fc6..ff7118b3 100755
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
"UUID": "C8mVSr-4nmPp2-pr5Vrz-CU4kg4",
"title": "Comty™",
"DevBuild": true,
- "version": "0.3.18",
+ "version": "0.4.02",
"stage": "dev-pre",
"description": "",
"author": "RageStudio",
@@ -37,8 +37,10 @@
"randomstring": "^1.1.5",
"react-animations": "^1.0.0",
"react-dazzle": "^1.4.0",
+ "react-emoji": "^0.5.0",
"react-google-recaptcha": "^2.0.1",
"react-helmet": "^5.2.1",
+ "react-linkify": "^1.0.0-alpha",
"react-perfect-scrollbar": "^1.5.8",
"react-reveal": "^1.2.2",
"react-scripts": "^3.4.1",
diff --git a/src/@ycore/libs/comty_ng/comty_user.js b/src/@ycore/libs/comty_ng/comty_user.js
index 92ed9ded..bd10a5fe 100755
--- a/src/@ycore/libs/comty_ng/comty_user.js
+++ b/src/@ycore/libs/comty_ng/comty_user.js
@@ -1,8 +1,27 @@
-import { API_Call, endpoints } from 'ycore'
+import { API_Call, endpoints, get_early } from 'ycore'
import { comty_rsa } from '../rs_cloud/pre'
export const comty_user = {
setData: () => {},
+ data: {
+ avatar: (callback,key) => {
+ if(!key) return false
+
+ try {
+ const payload = {username: key}
+ get_early.user((err,res) => {
+ const d = JSON.parse(res)['data']
+ return callback(d.avatar)
+ },payload)
+
+ } catch (error) {
+ return false
+ }
+
+
+ },
+
+ },
getFollowers: (callback, payload) => {
if (!payload)return false
const { user_id } = payload
diff --git a/src/@ycore/libs/ycore_sync/pre.js b/src/@ycore/libs/ycore_sync/pre.js
index 734c9fba..465cce8e 100755
--- a/src/@ycore/libs/ycore_sync/pre.js
+++ b/src/@ycore/libs/ycore_sync/pre.js
@@ -43,13 +43,15 @@ export const sync = {
},
FeedListen: (callback) => {
- const socket = io(endpoint);
+ const socket = io(`${endpoint}/feed`);
+
socket.on('pull_event', function (data) {
+ console.log(data)
callback(data)
});
},
emmitPost: (last_id) => {
- const socket = io(endpoint);
+ const socket = io(`${endpoint}/feed`);
socket.emit('push_event', last_id);
}
}
\ No newline at end of file
diff --git a/src/components/Layout/Secondary/index.less b/src/components/Layout/Secondary/index.less
index 45f0e78b..1227b926 100755
--- a/src/components/Layout/Secondary/index.less
+++ b/src/components/Layout/Secondary/index.less
@@ -105,7 +105,7 @@
padding: 30px 30px 30px 35px;
color: @secondary_container_1_color;
- background-color: #2d2d2d;
+ background-color: #F8F6F8;
&.full_open {
diff --git a/src/components/Layout/Secondary/renders.less b/src/components/Layout/Secondary/renders.less
index 9b5369b7..01faa713 100755
--- a/src/components/Layout/Secondary/renders.less
+++ b/src/components/Layout/Secondary/renders.less
@@ -4,9 +4,9 @@
width: 100%;
height: 100%;
font-family: @__Global_general_font_family;
- color: #ffffff;
+ color: #201F23;
font-size: 12px;
- h1,h2,h3,h4,h5{color:#ffffff}
+ h1,h2,h3,h4,h5{color:#201F23}
}
.UserContainer {
@@ -45,7 +45,7 @@
display: flex;
font-family: 'Poppins', sans-serif;
margin: 0 0 0 50px;
- color: #ffffff !important;
+ color: #201F23 !important;
}
.textAgo {
@@ -81,7 +81,7 @@
cursor: pointer;
}
- color: #ffffff !important;
+ color: #201F23 !important;
}
@@ -105,7 +105,7 @@
h3 {
font-family: "Poppins", sans-serif;
- color: #ffffff;
+ color: #201F23;
font-weight: 400;
font-size: 15px;
letter-spacing: -0.3px;
@@ -159,7 +159,7 @@
overflow-y: scroll!important;
position: relative;
width: 100%;
- background-color: #ffffff;
+ background-color: #201F23;
word-break: break-all;
.comment_title {
@@ -202,7 +202,7 @@
right: 0;
position: absolute;
z-index: 100;
- background-color: #ffffffd7;
+ background-color: #201F23d7;
padding-top: 20px;
padding-bottom: 60px;
border-radius: 0 0 0 32px;
@@ -229,7 +229,7 @@
}
.search_wrapper{
- color: #ffffff;
+ color: #201F23;
height: 100%;
width: 82%;
margin: auto;
@@ -255,7 +255,7 @@
border-radius: 8px;
padding: 10px;
word-break: break-all;
- color: #ffffff;
+ color: #201F23;
cursor: pointer;
.search_title {
@@ -272,7 +272,7 @@
margin: 0 5px 0 8px;
vertical-align: middle;
height: 100%;
- color: #ffffff;
+ color: #201F23;
line-height: 25px;
}
}
@@ -285,12 +285,12 @@
.secondary_hastags {
font-family: @__Global_general_font_family;
- color: #ffffff;
+ color: #201F23;
font-size: 12px;
.secondary_hastags_title{
- h2{color: #ffffff;}
+ h2{color: #201F23;}
}
.secondary_hastags_body{
@@ -336,7 +336,7 @@
height: 140px;
h1{
- color: #ffffff;
+ color: #201F23;
font-family: "Poppins", sans-serif;
font-size: 18px;
margin-bottom: 0;
diff --git a/src/components/Layout/Sider/default.js b/src/components/Layout/Sider/default.js
index 6a4cde7e..4244f705 100755
--- a/src/components/Layout/Sider/default.js
+++ b/src/components/Layout/Sider/default.js
@@ -16,8 +16,6 @@ export default class Sider_Default extends React.PureComponent {
diff --git a/src/components/Layout/Sider/default.less b/src/components/Layout/Sider/default.less
index 35b6478c..14e9bba6 100755
--- a/src/components/Layout/Sider/default.less
+++ b/src/components/Layout/Sider/default.less
@@ -20,7 +20,7 @@
}
.ant-menu-item {
- color: @left_sider_color;
+ color: #333;
}
.anticon {
@@ -129,9 +129,9 @@
:global {
.ant-menu-item {
padding: 0 !important;
- margin: 2px auto 2px auto;
+ margin: 2px auto 2px 24px;
width: 100%;
- text-align: center;
+ text-align: left;
}
}
}
\ No newline at end of file
diff --git a/src/pages/chats/Events.js b/src/pages/chats/Events.js
new file mode 100644
index 00000000..1716d10e
--- /dev/null
+++ b/src/pages/chats/Events.js
@@ -0,0 +1,11 @@
+module.exports = {
+ COMMUNITY_CHAT:"COMMUNITY_CHAT",
+ USER_CONNECTED:"USER_CONNECTED",
+ MESSAGE_RECIEVED:"MESSAGE_RECIEVED",
+ MESSAGE_SENT:"MESSAGE_SENT",
+ USER_DISCONNECTED:"USER_DISCONNECTED",
+ TYPING:"TYPING",
+ VERIFY_USER:"VERIFY_USER",
+ LOGOUT:"LOGOUT",
+ PRIVATE_MESSAGE:"PRIVATE_MESSAGE"
+}
\ No newline at end of file
diff --git a/src/pages/chats/chats/ChatContainer.js b/src/pages/chats/chats/ChatContainer.js
new file mode 100644
index 00000000..2da94211
--- /dev/null
+++ b/src/pages/chats/chats/ChatContainer.js
@@ -0,0 +1,183 @@
+import React, { Component } from 'react';
+import SideBar from './SideBar'
+import { MESSAGE_SENT, MESSAGE_RECIEVED, TYPING, PRIVATE_MESSAGE } from '../Events'
+import ChatHeading from './ChatHeading'
+import Messages from '../messages/Messages'
+import MessageInput from '../messages/MessageInput'
+import * as ycore from 'ycore'
+
+const userData = ycore.userData();
+
+export default class ChatContainer extends Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ chats:[],
+ activeChat:null
+ };
+ }
+
+ componentDidMount() {
+ const { socket } = this.props
+ this.initSocket(socket)
+ }
+
+ initSocket(socket){
+ socket.on(PRIVATE_MESSAGE, this.addChat)
+ }
+
+ sendOpenPrivateMessage = (reciever) => {
+ const { socket, user } = this.props
+ const { activeChat } = this.state
+ socket.emit(PRIVATE_MESSAGE, {reciever, sender:user.name, activeChat})
+
+ }
+
+ /*
+ * Reset the chat back to only the chat passed in.
+ * @param chat {Chat}
+ */
+ resetChat = (chat)=>{
+ return this.addChat(chat, true)
+ }
+
+ /*
+ * Adds chat to the chat container, if reset is true removes all chats
+ * and sets that chat to the main chat.
+ * Sets the message and typing socket events for the chat.
+ *
+ * @param chat {Chat} the chat to be added.
+ * @param reset {boolean} if true will set the chat as the only chat.
+ */
+ addChat = (chat, reset = false)=>{
+ const { socket } = this.props
+ const { chats } = this.state
+
+ console.log(chat)
+
+ const newChats = reset ? [chat] : [...chats, chat]
+ this.setState({chats:newChats, activeChat:reset ? chat : this.state.activeChat})
+
+ const messageEvent = `${MESSAGE_RECIEVED}-${chat.id}`
+ const typingEvent = `${TYPING}-${chat.id}`
+
+ socket.on(typingEvent, this.updateTypingInChat(chat.id))
+ socket.on(messageEvent, this.addMessageToChat(chat.id))
+ }
+
+ /*
+ * Returns a function that will
+ * adds message to chat with the chatId passed in.
+ *
+ * @param chatId {number}
+ */
+ addMessageToChat = (chatId)=>{
+ return message => {
+ const { chats } = this.state
+ let newChats = chats.map((chat)=>{
+ if(chat.id === chatId)
+ chat.messages.push(message)
+ return chat
+ })
+
+ this.setState({chats:newChats})
+ }
+ }
+
+ /*
+ * Updates the typing of chat with id passed in.
+ * @param chatId {number}
+ */
+ updateTypingInChat = (chatId) =>{
+ return ({isTyping, user})=>{
+ if(user !== this.props.user.name){
+
+ const { chats } = this.state
+
+ let newChats = chats.map((chat)=>{
+ if(chat.id === chatId){
+ if(isTyping && !chat.typingUsers.includes(user)){
+ chat.typingUsers.push(user)
+ }else if(!isTyping && chat.typingUsers.includes(user)){
+ chat.typingUsers = chat.typingUsers.filter(u => u !== user)
+ }
+ }
+ return chat
+ })
+ this.setState({chats:newChats})
+ }
+ }
+ }
+
+ /*
+ * Adds a message to the specified chat
+ * @param chatId {number} The id of the chat to be added to.
+ * @param message {string} The message to be added to the chat.
+ */
+ sendMessage = (chatId, message)=>{
+ const { socket } = this.props
+ socket.emit(MESSAGE_SENT, {chatId, message} )
+ }
+
+ /*
+ * Sends typing status to server.
+ * chatId {number} the id of the chat being typed in.
+ * typing {boolean} If the user is typing still or not.
+ */
+ sendTyping = (chatId, isTyping)=>{
+ const { socket } = this.props
+ socket.emit(TYPING, {chatId, isTyping})
+ }
+
+ setActiveChat = (activeChat)=>{
+ this.setState({activeChat})
+ }
+ render() {
+ const { user, logout } = this.props
+ const { chats, activeChat } = this.state
+ return (
+
+
+
+ {
+ activeChat !== null ? (
+
+
+
+
+ {
+ this.sendMessage(activeChat.id, message)
+ }
+ }
+ sendTyping={
+ (isTyping)=>{
+ this.sendTyping(activeChat.id, isTyping)
+ }
+ }
+ />
+
+
+ ):
+
+
Choose a chat!
+
+ }
+
+
+
+ );
+ }
+}
diff --git a/src/pages/chats/chats/ChatHeading.js b/src/pages/chats/chats/ChatHeading.js
new file mode 100644
index 00000000..dd71b21b
--- /dev/null
+++ b/src/pages/chats/chats/ChatHeading.js
@@ -0,0 +1,18 @@
+import React from 'react';
+
+export default function({name, numberOfUsers}) {
+
+ return (
+
+
+
{name}
+
+
+
{numberOfUsers ? numberOfUsers : null}
+
+
+
+
+ );
+
+}
diff --git a/src/pages/chats/chats/SideBar.js b/src/pages/chats/chats/SideBar.js
new file mode 100644
index 00000000..cfa2db81
--- /dev/null
+++ b/src/pages/chats/chats/SideBar.js
@@ -0,0 +1,80 @@
+import React, { Component } from 'react';
+import * as ycore from 'ycore'
+import * as antd from 'antd'
+
+const userData = ycore.userData()
+
+export default class SideBar extends React.PureComponent{
+ constructor(props){
+ super(props)
+ this.state = {
+ reciever:""
+ }
+ }
+ handleSubmit = (e) => {
+ e.preventDefault()
+ const { reciever } = this.state
+ const { onSendPrivateMessage } = this.props
+
+ onSendPrivateMessage(reciever)
+ this.setState({reciever:""})
+ }
+
+ render(){
+ const { chats, activeChat, user, setActiveChat } = this.props
+ const { reciever } = this.state
+
+ return (
+
+
+
+
+
{ (e.target === this.refs.user) && setActiveChat(null) }}>
+
+ {
+ chats.map((chat)=>{
+ if(chat.name){
+ const lastMessage = chat.messages[chat.messages.length - 1];
+ const chatSideName = chat.users.find((name)=>{
+ return name !== user.name
+ }) || "Unknown"
+ const ops_adata = chat.udata.find((i) =>{
+ return i.user !== user.name? i.avatar : null
+ })
+ const classNames = (activeChat && activeChat.id === chat.id) ? 'active' : ''
+ return(
+
{ setActiveChat(chat) } }
+ >
+
+
+
{chatSideName}
+ {lastMessage &&
{lastMessage.message}
}
+
+
+
+ )
+ }
+
+ return null
+ })
+ }
+
+
+
+
+ );
+
+ }
+}
diff --git a/src/pages/chats/index.js b/src/pages/chats/index.js
index 422e0865..0416c103 100644
--- a/src/pages/chats/index.js
+++ b/src/pages/chats/index.js
@@ -1,9 +1,82 @@
import React from 'react'
+import * as ycore from 'ycore'
+import * as antd from 'antd'
+import * as Icons from '@ant-design/icons'
+import io from 'socket.io-client'
+import config from 'config'
+import ReactEmoji from 'react-emoji';
+import { USER_CONNECTED, LOGOUT } from './Events'
+import ChatContainer from './chats/ChatContainer'
-export default class extends React.PureComponent{
- render(){
- return(
-
Chats
- )
+
+const userData = ycore.userData()
+
+const prefix = '[Messaging Socket] '
+const socketUrl = io(`${config.sync_server}/messaging_socket`);
+
+export default class Chats extends React.Component{
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ socket:null,
+ user:null,
+ conn: false
+ };
+ }
+
+ componentDidMount() {
+ this.initSocket()
+ }
+
+ /*
+ * Connect to and initializes the socket.
+ */
+ initSocket = async ()=>{
+ const socket = socketUrl
+
+ if(!this.state.conn){
+ await socket.on('connect', ()=>{
+ console.log(prefix, "Connected");
+ this.setState({ conn: true })
+ const payload = { id: userData.UserID, name: userData.username, avatar: userData.avatar }
+ this.setUser(payload)
+ })
}
+
+ this.setState({socket})
+
+ socket.on('disconnect', () => {
+ this.setState({ conn: false })
+ })
+
+ socket.on('reconnecting', () =>{
+ console.log(prefix, 'Trying to reconnect')
+ })
+ }
+
+ /*
+ * Sets the user property in state
+ * @param user {id:number, name:string}
+ */
+ setUser = (user)=>{
+ const { socket } = this.state
+ socket.emit(USER_CONNECTED, user);
+ this.setState({user})
+ }
+
+ render() {
+ const { socket, user } = this.state
+ return (
+
+ {
+ !user ?
+
initializes....
+ :
+
+ }
+
+ );
+ }
+
}
diff --git a/src/pages/chats/messages/MessageInput.js b/src/pages/chats/messages/MessageInput.js
new file mode 100644
index 00000000..ce7d9e56
--- /dev/null
+++ b/src/pages/chats/messages/MessageInput.js
@@ -0,0 +1,100 @@
+import React, { Component } from 'react';
+
+export default class MessageInput extends Component {
+
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ message:"",
+ isTyping:false
+ };
+
+ }
+
+ handleSubmit = (e)=>{
+ e.preventDefault()
+ this.sendMessage()
+ this.setState({message:""})
+ }
+
+ sendMessage = ()=>{
+ this.props.sendMessage(this.state.message)
+
+ }
+
+ componentWillUnmount() {
+ this.stopCheckingTyping()
+ }
+
+ sendTyping = ()=>{
+ this.lastUpdateTime = Date.now()
+ if(!this.state.isTyping){
+ this.setState({isTyping:true})
+ this.props.sendTyping(true)
+ this.startCheckingTyping()
+ }
+ }
+
+ /*
+ * startCheckingTyping
+ * Start an interval that checks if the user is typing.
+ */
+ startCheckingTyping = ()=>{
+ console.log("Typing");
+ this.typingInterval = setInterval(()=>{
+ if((Date.now() - this.lastUpdateTime) > 300){
+ this.setState({isTyping:false})
+ this.stopCheckingTyping()
+ }
+ }, 300)
+ }
+
+ /*
+ * stopCheckingTyping
+ * Start the interval from checking if the user is typing.
+ */
+ stopCheckingTyping = ()=>{
+ console.log("Stop Typing");
+ if(this.typingInterval){
+ clearInterval(this.typingInterval)
+ this.props.sendTyping(false)
+ }
+ }
+
+
+ render() {
+ const { message } = this.state
+ return (
+
+
+
+
+ );
+ }
+}
diff --git a/src/pages/chats/messages/Messages.js b/src/pages/chats/messages/Messages.js
new file mode 100644
index 00000000..cc4d2ec5
--- /dev/null
+++ b/src/pages/chats/messages/Messages.js
@@ -0,0 +1,61 @@
+import React, { Component } from 'react';
+
+export default class Messages extends Component {
+ constructor(props) {
+ super(props);
+
+ this.scrollDown = this.scrollDown.bind(this)
+ }
+
+ scrollDown(){
+ const { container } = this.refs
+ container.scrollTop = container.scrollHeight
+ }
+
+ componentDidMount() {
+ this.scrollDown()
+ }
+
+ componentDidUpdate(prevProps, prevState) {
+ this.scrollDown()
+ }
+
+ render() {
+ const { messages, user, typingUsers } = this.props
+ return (
+
+
+ {
+ messages.map((mes)=>{
+ return (
+
+
{mes.time}
+
+
{mes.message}
+
{mes.sender}
+
+
+
+ )
+ })
+ }
+ {
+ typingUsers.map((name)=>{
+ return (
+
+ {`${name} is typing . . .`}
+
+ )
+ })
+ }
+
+
+
+
+ );
+ }
+}
diff --git a/src/themes/base/index.less b/src/themes/base/index.less
index 67069d58..6b00b58b 100755
--- a/src/themes/base/index.less
+++ b/src/themes/base/index.less
@@ -128,7 +128,7 @@ body {
// }
// .primary_layout_*
-@primary_layout_backgroud: #2d2d2d;
+@primary_layout_backgroud: #F8F6F8; // #2d2d2d;
@primary_layout_container_backgroud: @__Global_layout_backgroud;
@primary_layout_container_border-rd: @__Global_layout_border-rd;
@@ -140,8 +140,8 @@ body {
@secondary_wrapper_hidden_width: 22vw;
@secondary_wrapper_showFull_width: 94.2%;
@secondary_wrapper_showHalf_width: 35vw;
-@secondary_container_bg_background: #201F23;
-@secondary_container_1_color: #fff;
+@secondary_container_bg_background: #F8F6F8;
+@secondary_container_1_color: #201F23;
@secondary_container_2_color: #201F23;
@secondary_container_2_backgroud: #fff;
@secondary_container_1_btn_backgroud: #4c4c4c;
@@ -152,7 +152,7 @@ body {
@secondaty_container_2_padding: 20px 15px 15px 15px;
// .left_sider*
-@left_sider_backgroud: #2d2d2d;
+@left_sider_backgroud: #F8F6F8;
@left_sider_color: #fff;
@left_sider_sizeIcons: 19px;
@left_sider_menu__onhover_backgroud: rgb(80, 80, 80);