55/* eslint-disable no-param-reassign */
66import React , { useState } from 'react' ;
77import PropTypes from 'prop-types' ;
8- import WebSocketMessage from '../../../components/display/WebSocketMessage' ;
9- import { WebSocketWindowProps } from '../../../../types' ;
10- import ImageDropzone from '../../../components/display/ImageDropzone' ;
118
129const { api } = window ;
1310
14- const WebSocketWindow : React . SFC < WebSocketWindowProps > = ( {
15- content,
16- outgoingMessages,
17- incomingMessages,
18- connection,
19- } ) => {
20- const [ inputMsgImg , setinputMsgImg ] = useState ( {
21- inputMsg : '' ,
22- inputImg : '' ,
11+ // TODO: ResponsePaneContainer.tsx should dispach state and we should pull it here, not drill it down
12+ const WebSocketWindow = ( { content, outgoingMessages, incomingMessages, connection} ) => {
13+ const [ inputFields , setInputFields ] = useState ( {
14+ msg : '' ,
15+ image : '' ,
2316 } ) ;
2417
2518 // updates the outgoing message when it changes
2619 const updateOutgoingMessage = ( value : any ) => {
2720 console . log ( 'updating msg' ) ;
2821 if ( value . includes ( 'data:image/' ) ) {
29- setinputMsgImg ( { ...inputMsgImg , inputImg : value } ) ;
22+ setInputFields ( { ...inputFields , image : value } ) ;
3023 } else {
31- setinputMsgImg ( { ...inputMsgImg , inputMsg : value } ) ;
24+ setInputFields ( { ...inputFields , msg : value } ) ;
3225 }
3326 } ;
3427
3528 // sends to WScontroller in main.js to send the message to server
29+ // TODO: doesn't handle the case of both fields being populated
3630 const sendToWSController = ( ) => {
37- if ( inputMsgImg . inputMsg ) {
38- api . send ( 'send-ws' , content , inputMsgImg . inputMsg ) ;
39- setinputMsgImg ( { inputMsg : '' , inputImg : '' } ) ;
40- } else if ( inputMsgImg . inputImg ) {
31+ if ( inputFields . msg ) {
32+ api . send ( 'send-ws' , content , inputFields . msg ) ;
33+ setInputFields ( { msg : '' , image : '' } ) ;
34+ } else if ( inputFields . image ) {
4135 console . log ( 'rerendering' ) ;
42- api . send ( 'send-ws' , content , inputMsgImg . inputImg ) ;
43- setinputMsgImg ( { inputMsg : '' , inputImg : '' } ) ;
36+ api . send ( 'send-ws' , content , inputFields . image ) ;
37+ setInputFields ( { msg : '' , image : '' } ) ;
4438 }
4539 // reset inputbox
4640 } ;
@@ -57,7 +51,7 @@ const WebSocketWindow: React.SFC<WebSocketWindowProps> = ({
5751 } ) ;
5852
5953 const data : any = await dataURL ( img ) ;
60- if ( inputMsgImg . inputImg !== data ) {
54+ if ( inputFields . image !== data ) {
6155 updateOutgoingMessage ( data ) ;
6256 }
6357 } ;
@@ -70,15 +64,14 @@ const WebSocketWindow: React.SFC<WebSocketWindowProps> = ({
7064 } ;
7165 // maps the messages to view in chronological order and by whom - self/server
7266 const combinedMessagesReactArr = outgoingMessages
73- . map ( ( message ) => {
74- message . source = 'client' ;
75-
67+ . map ( ( message : Record < string , unknown > ) => {
68+ message = { ... message , source : 'client' }
69+ console . log ( 'message after' , message )
7670 return message ;
7771 } )
7872 . concat (
79- incomingMessages . map ( ( message ) => {
80- message . source = 'server' ;
81-
73+ incomingMessages . map ( ( message : Record < string , unknown > ) => {
74+ message = { ...message , source : 'server' }
8275 return message ;
8376 } )
8477 )
@@ -113,7 +106,7 @@ const WebSocketWindow: React.SFC<WebSocketWindowProps> = ({
113106 < input
114107 className = "ml-1 mr-1 input is-small"
115108 id = "wsMsgInput"
116- value = { inputMsgImg . inputMsg }
109+ value = { inputFields . msg }
117110 onKeyPress = { handleKeyPress }
118111 placeholder = "Message"
119112 onChange = { ( e ) => updateOutgoingMessage ( e . target . value ) }
@@ -167,3 +160,93 @@ WebSocketWindow.propTypes = {
167160} ;
168161
169162export default WebSocketWindow ;
163+
164+ // This was separate file, maybe re-export eventually
165+
166+ const WebSocketMessage = ( {
167+ source,
168+ timeReceived,
169+ data,
170+ index,
171+ } ) => {
172+ // conditional classNames and id for messages for styling depending on source
173+ const webSocketMessageClassNames =
174+ source === 'server'
175+ ? 'websocket_message websocket_message-server'
176+ : 'websocket_message websocket_message-client' ;
177+ const webSocketMessageIDNames =
178+ source === 'server'
179+ ? 'id_websocket_message-server'
180+ : 'id_websocket_message-client' ;
181+
182+ const message_background =
183+ source === 'server' ? 'server-background' : 'client-background' ;
184+ const message_sender = source === 'server' ? 'server' : 'client' ;
185+
186+ // timestamp for messages
187+ const buildTime = ( time : number ) : string => {
188+ const hours = new Date ( time ) . getHours ( ) ;
189+ const h = hours >= 10 ? `${ hours } ` : `0${ JSON . stringify ( hours ) } ` ;
190+ const minutes = new Date ( time ) . getMinutes ( ) ;
191+ const m = minutes >= 10 ? `${ minutes } ` : `0${ JSON . stringify ( minutes ) } ` ;
192+ const seconds = new Date ( time ) . getSeconds ( ) ;
193+ const s = seconds >= 10 ? `${ seconds } ` : `0${ JSON . stringify ( seconds ) } ` ;
194+ return `${ h } :${ m } :${ s } ` ;
195+ } ;
196+
197+ return (
198+ < div >
199+ < div className = { webSocketMessageClassNames } id = { `ws-msg-${ index } ` } >
200+ < div className = { message_background } >
201+ < div className = "websocket_message-data" >
202+ { typeof data === 'object' ? (
203+ // decode buffer to dataURI
204+ < img src = { new TextDecoder ( 'utf-8' ) . decode ( data ) } alt = "img" />
205+ ) : (
206+ < div id = { webSocketMessageIDNames } > { data } </ div >
207+ ) }
208+ </ div >
209+ < div className = "websocket_message-time" >
210+ { buildTime ( timeReceived ) }
211+ </ div >
212+ </ div >
213+ </ div >
214+ < div className = { message_sender } > { message_sender } </ div >
215+ </ div >
216+ ) ;
217+ } ;
218+
219+ WebSocketMessage . propTypes = {
220+ source : PropTypes . string . isRequired ,
221+ data : PropTypes . any . isRequired ,
222+ timeReceived : PropTypes . any . isRequired ,
223+ } ;
224+
225+ // This was separate file, maybe re-export eventually to
226+
227+ import { useDropzone } from 'react-dropzone' ;
228+
229+ function ImageDropzone ( { onFileChange } ) {
230+ const { acceptedFiles, getRootProps, getInputProps } = useDropzone ( ) ;
231+
232+ const files = acceptedFiles . map ( ( file ) => (
233+ < li key = { file . path } > image { file . name } uploaded</ li >
234+ ) ) ;
235+
236+ return (
237+ < section className = "container" >
238+ < div { ...getRootProps ( { className : 'dropzone' } ) } >
239+ < input id = "wsFileInput" { ...getInputProps ( ) } />
240+ < input
241+ className = "ml-1 mr-1 input is-small"
242+ id = "wsDragNdrop"
243+ placeholder = { `Drag 'n' drop your image here, or click to select a file` }
244+ onChange = { ( ) => { onFileChange ( acceptedFiles ) } }
245+ />
246+ </ div >
247+ < aside >
248+ < ul > { files } </ ul >
249+ </ aside >
250+ </ section >
251+ ) ;
252+ }
0 commit comments