1- import React from 'react' ;
1+ import React , { useState , useEffect , useRef } from 'react' ;
22import styled from 'styled-components' ;
33import { sortBy , takeRight } from 'lodash-es' ;
44import { inject , observer } from 'app/componentConnectors' ;
@@ -22,126 +22,115 @@ const Messages = styled.div`
2222 flex: 1;
2323` ;
2424
25- class ChatComponent extends React . Component {
26- state = {
27- value : '' ,
28- } ;
25+ const ChatComponent = ( { signals, store } ) => {
26+ const [ value , setValue ] = useState ( '' ) ;
27+ const [ height , setHeight ] = useState ( '' ) ;
28+ const messagesRef = useRef ( null ) ;
29+ function scrollDown ( ) {
30+ if ( messagesRef . current ) {
31+ messagesRef . current . scrollTop = messagesRef . current . scrollHeight ;
32+ }
33+ }
34+ useEffect ( scrollDown ) ;
2935
30- handleKeyDown = ( e : KeyboardEvent ) => {
36+ const handleKeyDown = e => {
3137 if ( e . keyCode === ENTER && ! e . shiftKey ) {
3238 e . preventDefault ( ) ;
3339 e . stopPropagation ( ) ;
3440 // Enter
35- this . props . signals . live . onSendChat ( {
36- message : this . state . value ,
41+ signals . live . onSendChat ( {
42+ message : value ,
3743 } ) ;
38- this . setState ( { value : '' } ) ;
39- if ( this . messages ) {
40- this . messages . scrollTop = this . messages . scrollHeight ;
41- }
44+ setValue ( '' ) ;
45+ scrollDown ( ) ;
4246 }
4347 } ;
4448
45- handleChange = e => {
46- this . setState ( { value : e . target . value } ) ;
49+ const handleChange = e => {
50+ setValue ( e . target . value ) ;
4751 } ;
4852
49- componentDidUpdate ( ) {
50- if ( this . messages ) {
51- this . messages . scrollTop = this . messages . scrollHeight ;
52- }
53- }
54-
55- componentDidMount ( ) {
56- if ( this . messages ) {
57- this . messages . scrollTop = this . messages . scrollHeight ;
58- }
59- }
60-
61- render ( ) {
62- const { store } = this . props ;
63- const { messages, users } = store . live . roomInfo . chat ;
64- const currentUserId = store . live . liveUserId ;
65- const roomInfoUsers = store . live . roomInfo . users ;
53+ const { messages, users } = store . live . roomInfo . chat ;
54+ const currentUserId = store . live . liveUserId ;
55+ const roomInfoUsers = store . live . roomInfo . users ;
6656
67- return (
68- < Container
69- ref = { el => {
70- this . messages = el ;
71- } }
72- >
73- < Messages >
74- { messages . length > 0 ? (
75- sortBy ( takeRight ( messages , 100 ) , 'date' ) . map ( ( message , i ) => {
76- const metadata = roomInfoUsers . find ( u => u . id === message . userId ) ;
77- const color = metadata
78- ? `rgb(${ metadata . color [ 0 ] } , ${ metadata . color [ 1 ] } , ${
79- metadata . color [ 2 ]
80- } )`
81- : '#636363' ;
82- const name = users . get
83- ? users . get ( message . userId )
84- : users [ message . userId ] ;
85- return (
86- < div key = { message . date } >
87- { ( i === 0 || messages [ i - 1 ] . userId !== message . userId ) && (
88- < div
89- style = { {
90- color,
91- fontWeight : 600 ,
92- marginBottom : '0.25rem' ,
93- marginTop : '0.5rem' ,
94- } }
95- >
96- { name }
97- { currentUserId === message . userId && ' (you)' }
98- { ! metadata && ' (left)' }
99- </ div >
100- ) }
57+ return (
58+ < Container
59+ ref = { el => {
60+ messagesRef . current = el ;
61+ } }
62+ >
63+ < Messages >
64+ { messages . length > 0 ? (
65+ sortBy ( takeRight ( messages , 100 ) , 'date' ) . map ( ( message , i ) => {
66+ const metadata = roomInfoUsers . find ( u => u . id === message . userId ) ;
67+ const color = metadata
68+ ? `rgb(${ metadata . color [ 0 ] } , ${ metadata . color [ 1 ] } , ${
69+ metadata . color [ 2 ]
70+ } )`
71+ : '#636363' ;
72+ const name = users . get
73+ ? users . get ( message . userId )
74+ : users [ message . userId ] ;
75+ return (
76+ < div key = { message . date } >
77+ { ( i === 0 || messages [ i - 1 ] . userId !== message . userId ) && (
10178 < div
10279 style = { {
103- color : 'rgba(255, 255, 255, 0.7)' ,
104- fontWeight : 400 ,
105- marginBottom : '.25rem' ,
80+ color,
81+ fontWeight : 600 ,
82+ marginBottom : '0.25rem' ,
83+ marginTop : '0.5rem' ,
10684 } }
10785 >
108- { message . message . split ( '\n' ) . map ( m => (
109- < span key = { m } >
110- { m }
111- < br />
112- </ span >
113- ) ) }
86+ { name }
87+ { currentUserId === message . userId && ' (you)' }
88+ { ! metadata && ' (left)' }
11489 </ div >
90+ ) }
91+ < div
92+ style = { {
93+ color : 'rgba(255, 255, 255, 0.7)' ,
94+ fontWeight : 400 ,
95+ marginBottom : '.25rem' ,
96+ } }
97+ >
98+ { message . message . split ( '\n' ) . map ( m => (
99+ < span key = { m } >
100+ { m }
101+ < br />
102+ </ span >
103+ ) ) }
115104 </ div >
116- ) ;
117- } )
118- ) : (
119- < div
120- style = { {
121- fontStyle : 'italic' ,
122- color : 'rgba(255, 255, 255, 0.5) ' ,
123- } }
124- >
125- No messages, start sending some!
126- </ div >
127- ) }
128- </ Messages >
129- < AutosizeTextArea
130- useCacheForDOMMeasurements
131- value = { this . state . value }
132- onChange = { this . handleChange }
133- placeholder = "Send a message..."
134- style = { {
135- width : '100%' ,
136- minHeight : this . state . height ,
137- marginTop : '0.5rem' ,
138- } }
139- onKeyDown = { this . handleKeyDown }
140- onHeightChange = { height => this . setState ( { height } ) }
141- />
142- </ Container >
143- ) ;
144- }
145- }
105+ </ div >
106+ ) ;
107+ } )
108+ ) : (
109+ < div
110+ style = { {
111+ fontStyle : 'italic ' ,
112+ color : 'rgba(255, 255, 255, 0.5)' ,
113+ } }
114+ >
115+ No messages, start sending some!
116+ </ div >
117+ ) }
118+ </ Messages >
119+ < AutosizeTextArea
120+ useCacheForDOMMeasurements
121+ value = { value }
122+ onChange = { handleChange }
123+ placeholder = "Send a message..."
124+ style = { {
125+ width : '100%' ,
126+ minHeight : height ,
127+ marginTop : '0.5rem' ,
128+ } }
129+ onKeyDown = { handleKeyDown }
130+ onHeightChange = { setHeight }
131+ / >
132+ </ Container >
133+ ) ;
134+ } ;
146135
147136export const Chat = inject ( 'signals' , 'store' ) ( observer ( ChatComponent ) ) ;
0 commit comments