2022-01-13 19:22:54 +00:00
import React , { Component } from 'react' ;
2022-04-05 14:25:53 +00:00
import { withTranslation , Trans } from "react-i18next" ;
2022-03-24 13:41:32 +00:00
import { Button , Link , Badge , TextField , Grid , Container , Card , CardHeader , Paper , Avatar , FormHelperText , Typography } from "@mui/material" ;
2022-03-10 21:35:16 +00:00
import ReconnectingWebSocket from 'reconnecting-websocket' ;
2022-01-13 19:22:54 +00:00
2022-04-05 14:25:53 +00:00
class Chat extends Component {
2022-01-13 19:22:54 +00:00
constructor ( props ) {
super ( props ) ;
}
state = {
messages : [ ] ,
value : '' ,
2022-03-10 21:35:16 +00:00
connected : false ,
peer _connected : false ,
2022-01-13 19:22:54 +00:00
} ;
2022-03-10 21:35:16 +00:00
rws = new ReconnectingWebSocket ( 'ws://' + window . location . host + '/ws/chat/' + this . props . orderId + '/' ) ;
2022-01-13 19:22:54 +00:00
componentDidMount ( ) {
2022-03-10 21:35:16 +00:00
this . rws . addEventListener ( 'open' , ( ) => {
console . log ( 'Connected!' ) ;
this . setState ( { connected : true } ) ;
this . rws . send ( JSON . stringify ( {
type : "message" ,
message : 'just-connected' ,
nick : this . props . ur _nick ,
} ) ) ;
} ) ;
this . rws . addEventListener ( 'message' , ( message ) => {
2022-01-13 19:22:54 +00:00
const dataFromServer = JSON . parse ( message . data ) ;
console . log ( 'Got reply!' , dataFromServer . type ) ;
2022-03-10 21:35:16 +00:00
if ( dataFromServer ) {
if ( dataFromServer . message != 'just-connected' & dataFromServer . message != 'peer-disconnected' ) {
this . setState ( ( state ) =>
( {
messages : [ ... state . messages ,
{
msg : dataFromServer . message ,
userNick : dataFromServer . user _nick ,
} ] ,
} )
)
}
this . setState ( { peer _connected : dataFromServer . peer _connected } )
2022-01-13 19:22:54 +00:00
}
2022-03-10 21:35:16 +00:00
} ) ;
2022-01-13 19:22:54 +00:00
2022-03-10 21:35:16 +00:00
this . rws . addEventListener ( 'close' , ( ) => {
console . log ( 'Socket is closed. Reconnect will be attempted' ) ;
this . setState ( { connected : false } ) ;
} ) ;
this . rws . addEventListener ( 'error' , ( ) => {
console . error ( 'Socket encountered error: Closing socket' ) ;
} ) ;
2022-01-13 19:22:54 +00:00
}
2022-01-14 00:43:26 +00:00
componentDidUpdate ( ) {
this . scrollToBottom ( ) ;
}
scrollToBottom = ( ) => {
this . messagesEnd . scrollIntoView ( { behavior : "smooth" } ) ;
}
2022-01-13 19:22:54 +00:00
onButtonClicked = ( e ) => {
2022-03-02 13:12:27 +00:00
if ( this . state . value != '' ) {
2022-03-10 21:35:16 +00:00
this . rws . send ( JSON . stringify ( {
2022-03-02 13:12:27 +00:00
type : "message" ,
message : this . state . value ,
nick : this . props . ur _nick ,
} ) ) ;
this . state . value = ''
}
2022-01-13 19:22:54 +00:00
e . preventDefault ( ) ;
}
render ( ) {
2022-04-05 14:25:53 +00:00
const { t } = this . props ;
2022-01-13 19:22:54 +00:00
return (
2022-03-11 14:33:07 +00:00
< Container component = "main" maxWidth = "xs" >
< Grid container xs = { 12 } spacing = { 0.5 } >
< Grid item xs = { 0.3 } / >
< Grid item xs = { 5.5 } >
< Paper elevation = { 1 } style = { this . state . connected ? { backgroundColor : '#e8ffe6' } : { backgroundColor : '#FFF1C5' } } >
2022-03-24 22:18:01 +00:00
< Typography variant = 'caption' sx = { { color : '#111111' } } >
2022-04-05 14:25:53 +00:00
{ t ( "You" ) + ": " } { this . state . connected ? t ( "connected" ) : t ( "disconnected" ) }
2022-03-11 14:33:07 +00:00
< / T y p o g r a p h y >
< / P a p e r >
2022-03-10 21:35:16 +00:00
< / G r i d >
2022-03-11 14:33:07 +00:00
< Grid item xs = { 0.4 } / >
< Grid item xs = { 5.5 } >
< Paper elevation = { 1 } style = { this . state . peer _connected ? { backgroundColor : '#e8ffe6' } : { backgroundColor : '#FFF1C5' } } >
2022-03-24 22:18:01 +00:00
< Typography variant = 'caption' sx = { { color : '#111111' } } >
2022-04-05 14:25:53 +00:00
{ t ( "Peer" ) + ": " } { this . state . peer _connected ? t ( "connected" ) : t ( "disconnected" ) }
2022-03-11 14:33:07 +00:00
< / T y p o g r a p h y >
< / P a p e r >
< / G r i d >
< Grid item xs = { 0.3 } / >
< / G r i d >
2022-03-24 22:18:01 +00:00
< Paper elevation = { 1 } style = { { height : '300px' , maxHeight : '300px' , width : '280px' , overflow : 'auto' , backgroundColor : '#F7F7F7' } } >
2022-01-13 19:22:54 +00:00
{ this . state . messages . map ( message => < >
2022-01-13 20:41:48 +00:00
< Card elevation = { 5 } align = "left" >
{ /* If message sender is not our nick, gray color, if it is our nick, green color */ }
2022-01-22 23:05:03 +00:00
{ message . userNick == this . props . ur _nick ?
2022-03-24 22:18:01 +00:00
< CardHeader sx = { { color : '#111111' } }
2022-01-13 20:41:48 +00:00
avatar = {
2022-03-10 21:35:16 +00:00
< Badge variant = "dot" overlap = "circular" badgeContent = "" color = { this . state . connected ? "success" : "error" } >
< Avatar className = "flippedSmallAvatar"
alt = { message . userNick }
src = { window . location . origin + '/static/assets/avatars/' + message . userNick + '.png' }
/ >
< / B a d g e >
2022-01-13 20:41:48 +00:00
}
2022-03-11 14:33:07 +00:00
style = { { backgroundColor : '#eeeeee' } }
2022-01-13 20:41:48 +00:00
title = { message . userNick }
subheader = { message . msg }
2022-03-24 22:18:01 +00:00
subheaderTypographyProps = { { sx : { wordWrap : "break-word" , width : '200px' , color : '#444444' } } }
2022-01-13 20:41:48 +00:00
/ >
:
2022-03-24 22:18:01 +00:00
< CardHeader sx = { { color : '#111111' } }
2022-03-02 13:49:12 +00:00
avatar = {
2022-03-10 21:35:16 +00:00
< Badge variant = "dot" overlap = "circular" badgeContent = "" color = { this . state . peer _connected ? "success" : "error" } >
< Avatar className = "flippedSmallAvatar"
alt = { message . userNick }
src = { window . location . origin + '/static/assets/avatars/' + message . userNick + '.png' }
/ >
< / B a d g e >
2022-03-02 13:49:12 +00:00
}
2022-03-11 14:33:07 +00:00
style = { { backgroundColor : '#fafafa' } }
2022-03-02 13:49:12 +00:00
title = { message . userNick }
subheader = { message . msg }
2022-03-24 22:18:01 +00:00
subheaderTypographyProps = { { sx : { wordWrap : "break-word" , width : '200px' , color : '#444444' } } }
2022-03-02 13:49:12 +00:00
/ > }
2022-01-13 19:22:54 +00:00
< / C a r d >
< / > ) }
2022-01-14 00:43:26 +00:00
< div style = { { float : "left" , clear : "both" } } ref = { ( el ) => { this . messagesEnd = el ; } } > < / d i v >
2022-01-13 19:22:54 +00:00
< / P a p e r >
< form noValidate onSubmit = { this . onButtonClicked } >
< Grid containter alignItems = "stretch" style = { { display : "flex" } } >
2022-03-10 21:35:16 +00:00
< Grid item alignItems = "stretch" style = { { display : "flex" } } >
2022-01-13 19:22:54 +00:00
< TextField
2022-04-05 14:25:53 +00:00
label = { t ( "Type a message" ) }
2022-03-10 21:35:16 +00:00
variant = "standard"
2022-01-13 19:22:54 +00:00
size = "small"
2022-04-05 14:25:53 +00:00
helperText = { this . state . connected ? null : t ( "Connecting..." ) }
2022-01-13 19:22:54 +00:00
value = { this . state . value }
onChange = { e => {
this . setState ( { value : e . target . value } ) ;
this . value = this . state . value ;
} }
2022-03-10 21:35:16 +00:00
sx = { { width : 214 } }
2022-01-13 19:22:54 +00:00
/ >
< / G r i d >
< Grid item alignItems = "stretch" style = { { display : "flex" } } >
2022-04-05 14:25:53 +00:00
< Button disabled = { ! this . state . connected } type = "submit" variant = "contained" color = "primary" > { t ( "Send" ) } < / B u t t o n >
2022-01-13 19:22:54 +00:00
< / G r i d >
< / G r i d >
< / f o r m >
2022-03-02 12:57:52 +00:00
< FormHelperText >
2022-04-05 14:25:53 +00:00
{ t ( "The chat has no memory: if you leave, messages are lost." ) } < Link target = "_blank" href = "https://github.com/Reckless-Satoshi/robosats/blob/main/docs/sensitive-data-PGP-guide.md/" > { t ( "Learn easy PGP encryption." ) } < / L i n k >
2022-03-02 12:57:52 +00:00
< / F o r m H e l p e r T e x t >
2022-01-13 19:22:54 +00:00
< / C o n t a i n e r >
)
}
}
2022-04-05 14:25:53 +00:00
export default withTranslation ( ) ( Chat ) ;