Skip to content

Commit 9284673

Browse files
committed
redux mutation fix
1 parent f7e09df commit 9284673

File tree

3 files changed

+675
-674
lines changed

3 files changed

+675
-674
lines changed
Lines changed: 163 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -1,164 +1,163 @@
1-
/* eslint-disable @typescript-eslint/no-explicit-any */
2-
/* eslint-disable @typescript-eslint/no-unsafe-call */
3-
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
4-
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
5-
/* eslint-disable no-param-reassign */
6-
import React, { useState } from 'react';
7-
import PropTypes from 'prop-types';
8-
9-
import ImageDropzone from './ImageDropzone';
10-
11-
const { api } = window;
12-
13-
// TODO: ResponsePaneContainer.tsx should dispach state and we should pull it here, not drill it down
14-
const WebSocketWindow = ({content, outgoingMessages, incomingMessages, connection}) => {
15-
const [inputFields, setInputFields] = useState({
16-
msg: '',
17-
image: '',
18-
});
19-
20-
// updates the outgoing message when it changes
21-
const updateOutgoingMessage = (value: any) => {
22-
console.log('updating msg');
23-
if (value.includes('data:image/')) {
24-
setInputFields({ ...inputFields, image: value });
25-
} else {
26-
setInputFields({ ...inputFields, msg: value });
27-
}
28-
};
29-
30-
// sends to WScontroller in main.js to send the message to server
31-
// TODO: doesn't handle the case of both fields being populated
32-
const sendToWSController = () => {
33-
if (inputFields.msg) {
34-
api.send('send-ws', content, inputFields.msg);
35-
setInputFields({ msg: '', image: '' });
36-
} else if (inputFields.image) {
37-
console.log('rerendering');
38-
api.send('send-ws', content, inputFields.image);
39-
setInputFields({ msg: '', image: '' });
40-
}
41-
// reset inputbox
42-
};
43-
44-
const handleFileChange = async (file: any) => {
45-
const img = file[0];
46-
47-
const dataURL = (file: any) =>
48-
new Promise((resolve, reject) => {
49-
const reader = new FileReader();
50-
reader.readAsDataURL(img);
51-
reader.onload = () => resolve(reader.result);
52-
reader.onerror = (error) => reject(error);
53-
});
54-
55-
const data: any = await dataURL(img);
56-
if (inputFields.image !== data) {
57-
updateOutgoingMessage(data);
58-
}
59-
};
60-
61-
// when you press enter send the message, send message to socket
62-
const handleKeyPress = (event: { key: string }) => {
63-
if (event.key === 'Enter') {
64-
sendToWSController();
65-
}
66-
};
67-
// maps the messages to view in chronological order and by whom - self/server
68-
const combinedMessagesReactArr = outgoingMessages
69-
.map((message: Record<string, unknown>) => {
70-
message = {...message, source: 'client'}
71-
console.log('message after', message)
72-
return message;
73-
})
74-
.concat(
75-
incomingMessages.map((message: Record<string, unknown>) => {
76-
message = {...message, source: 'server'}
77-
return message;
78-
})
79-
)
80-
// sorts by time
81-
.sort((a, b) => a.timeReceived - b.timeReceived)
82-
// then maps the combined array to a WebSocket Component
83-
// conditionally rendering messages or images
84-
.map((message, index) => (
85-
<WebSocketMessage
86-
key={index}
87-
index={index}
88-
source={message.source}
89-
data={message.data}
90-
timeReceived={message.timeReceived}
91-
/>
92-
));
93-
94-
// sets the message style depending on if the connection is open
95-
// hides when connection is not open
96-
const messageInputStyles = {
97-
display: connection === 'open' ? 'block' : 'none',
98-
};
99-
100-
// exports the chatLog- sends it to the backend
101-
const exportChatLog = (event: any) => {
102-
api.send('exportChatLog', outgoingMessages, incomingMessages);
103-
};
104-
105-
return (
106-
<div className="websocket_container is-tall is-flex is-flex-direction-column p-3">
107-
<div className="is-flex is-align-items-center">
108-
<input
109-
className="ml-1 mr-1 input is-small"
110-
id="wsMsgInput"
111-
value={inputFields.msg}
112-
onKeyPress={handleKeyPress}
113-
placeholder="Message"
114-
onChange={(e) => updateOutgoingMessage(e.target.value)}
115-
/>
116-
<button
117-
className="button is-primary is-outlined is-small"
118-
id="wsSendMsgBtn"
119-
onClick={sendToWSController}
120-
type="button"
121-
>
122-
Send Message
123-
</button>
124-
</div>
125-
<div className="is-flex is-align-items-center">
126-
<ImageDropzone onFileChange={handleFileChange} />
127-
<button
128-
className="button is-primary is-outlined is-small"
129-
id="wsSendImgBtn"
130-
onClick={sendToWSController}
131-
type="button"
132-
>
133-
Send image
134-
</button>
135-
</div>
136-
137-
{/* only show the ws messages when connection is open */}
138-
{connection === 'open' && (
139-
<>
140-
<div className="websocket_message_container m-3">
141-
{combinedMessagesReactArr}
142-
</div>
143-
144-
<button
145-
className="button is-primary is-outlined is-small"
146-
onClick={exportChatLog}
147-
type="button"
148-
>
149-
Export Log
150-
</button>
151-
</>
152-
)}
153-
</div>
154-
);
155-
};
156-
157-
WebSocketWindow.propTypes = {
158-
outgoingMessages: PropTypes.array.isRequired,
159-
incomingMessages: PropTypes.array.isRequired,
160-
content: PropTypes.any.isRequired,
161-
connection: PropTypes.string.isRequired,
162-
};
163-
164-
export default WebSocketWindow;
1+
/* eslint-disable @typescript-eslint/no-explicit-any */
2+
/* eslint-disable @typescript-eslint/no-unsafe-call */
3+
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
4+
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
5+
/* eslint-disable no-param-reassign */
6+
import React, { useState } from 'react';
7+
import PropTypes from 'prop-types';
8+
9+
import ImageDropzone from './ImageDropzone';
10+
11+
const { api } = window;
12+
13+
// TODO: ResponsePaneContainer.tsx should dispach state and we should pull it here, not drill it down
14+
const WebSocketWindow = ({content, outgoingMessages, incomingMessages, connection}) => {
15+
const [inputFields, setInputFields] = useState({
16+
msg: '',
17+
image: '',
18+
});
19+
20+
// updates the outgoing message when it changes
21+
const updateOutgoingMessage = (value: any) => {
22+
console.log('updating msg');
23+
if (value.includes('data:image/')) {
24+
setInputFields({ ...inputFields, image: value });
25+
} else {
26+
setInputFields({ ...inputFields, msg: value });
27+
}
28+
};
29+
30+
// sends to WScontroller in main.js to send the message to server
31+
// TODO: doesn't handle the case of both fields being populated
32+
const sendToWSController = () => {
33+
if (inputFields.msg) {
34+
api.send('send-ws', content, inputFields.msg);
35+
setInputFields({ msg: '', image: '' });
36+
} else if (inputFields.image) {
37+
console.log('rerendering');
38+
api.send('send-ws', content, inputFields.image);
39+
setInputFields({ msg: '', image: '' });
40+
}
41+
// reset inputbox
42+
};
43+
44+
const handleFileChange = async (file: any) => {
45+
const img = file[0];
46+
47+
const dataURL = (file: any) =>
48+
new Promise((resolve, reject) => {
49+
const reader = new FileReader();
50+
reader.readAsDataURL(img);
51+
reader.onload = () => resolve(reader.result);
52+
reader.onerror = (error) => reject(error);
53+
});
54+
55+
const data: any = await dataURL(img);
56+
if (inputFields.image !== data) {
57+
updateOutgoingMessage(data);
58+
}
59+
};
60+
61+
// when you press enter send the message, send message to socket
62+
const handleKeyPress = (event: { key: string }) => {
63+
if (event.key === 'Enter') {
64+
sendToWSController();
65+
}
66+
};
67+
// maps the messages to view in chronological order and by whom - self/server
68+
const combinedMessagesReactArr = outgoingMessages
69+
.map((message: Record<string, unknown>) => {
70+
message = {...message, source: 'client'}
71+
return message;
72+
})
73+
.concat(
74+
incomingMessages.map((message: Record<string, unknown>) => {
75+
message = {...message, source: 'server'}
76+
return message;
77+
})
78+
)
79+
// sorts by time
80+
.sort((a, b) => a.timeReceived - b.timeReceived)
81+
// then maps the combined array to a WebSocket Component
82+
// conditionally rendering messages or images
83+
.map((message, index) => (
84+
<WebSocketMessage
85+
key={index}
86+
index={index}
87+
source={message.source}
88+
data={message.data}
89+
timeReceived={message.timeReceived}
90+
/>
91+
));
92+
93+
// sets the message style depending on if the connection is open
94+
// hides when connection is not open
95+
const messageInputStyles = {
96+
display: connection === 'open' ? 'block' : 'none',
97+
};
98+
99+
// exports the chatLog- sends it to the backend
100+
const exportChatLog = (event: any) => {
101+
api.send('exportChatLog', outgoingMessages, incomingMessages);
102+
};
103+
104+
return (
105+
<div className="websocket_container is-tall is-flex is-flex-direction-column p-3">
106+
<div className="is-flex is-align-items-center">
107+
<input
108+
className="ml-1 mr-1 input is-small"
109+
id="wsMsgInput"
110+
value={inputFields.msg}
111+
onKeyPress={handleKeyPress}
112+
placeholder="Message"
113+
onChange={(e) => updateOutgoingMessage(e.target.value)}
114+
/>
115+
<button
116+
className="button is-primary is-outlined is-small"
117+
id="wsSendMsgBtn"
118+
onClick={sendToWSController}
119+
type="button"
120+
>
121+
Send Message
122+
</button>
123+
</div>
124+
<div className="is-flex is-align-items-center">
125+
<ImageDropzone onFileChange={handleFileChange} />
126+
<button
127+
className="button is-primary is-outlined is-small"
128+
id="wsSendImgBtn"
129+
onClick={sendToWSController}
130+
type="button"
131+
>
132+
Send image
133+
</button>
134+
</div>
135+
136+
{/* only show the ws messages when connection is open */}
137+
{connection === 'open' && (
138+
<>
139+
<div className="websocket_message_container m-3">
140+
{combinedMessagesReactArr}
141+
</div>
142+
143+
<button
144+
className="button is-primary is-outlined is-small"
145+
onClick={exportChatLog}
146+
type="button"
147+
>
148+
Export Log
149+
</button>
150+
</>
151+
)}
152+
</div>
153+
);
154+
};
155+
156+
WebSocketWindow.propTypes = {
157+
outgoingMessages: PropTypes.array.isRequired,
158+
incomingMessages: PropTypes.array.isRequired,
159+
content: PropTypes.any.isRequired,
160+
connection: PropTypes.string.isRequired,
161+
};
162+
163+
export default WebSocketWindow;

0 commit comments

Comments
 (0)