mirror of
https://github.com/RoboSats/robosats.git
synced 2025-08-10 07:00:21 +00:00
Create WebsocketWebClient (#277)
* Create WebsocketWebClient * Remove unused lines * Code review
This commit is contained in:
@ -20,6 +20,7 @@ import { saveAsJson } from '../utils/saveFile';
|
|||||||
import { AuditPGPDialog } from './Dialogs';
|
import { AuditPGPDialog } from './Dialogs';
|
||||||
import RobotAvatar from './Robots/RobotAvatar';
|
import RobotAvatar from './Robots/RobotAvatar';
|
||||||
import { systemClient } from '../services/System';
|
import { systemClient } from '../services/System';
|
||||||
|
import { websocketClient } from '../services/Websocket';
|
||||||
|
|
||||||
// Icons
|
// Icons
|
||||||
import CheckIcon from '@mui/icons-material/Check';
|
import CheckIcon from '@mui/icons-material/Check';
|
||||||
@ -43,6 +44,7 @@ class Chat extends Component {
|
|||||||
messages: [],
|
messages: [],
|
||||||
value: '',
|
value: '',
|
||||||
connected: false,
|
connected: false,
|
||||||
|
connection: null,
|
||||||
peer_connected: false,
|
peer_connected: false,
|
||||||
audit: false,
|
audit: false,
|
||||||
showPGP: new Array(),
|
showPGP: new Array(),
|
||||||
@ -52,34 +54,45 @@ class Chat extends Component {
|
|||||||
scrollNow: false,
|
scrollNow: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
rws = new ReconnectingWebSocket(
|
|
||||||
'ws://' + window.location.host + '/ws/chat/' + this.props.orderId + '/',
|
|
||||||
[],
|
|
||||||
{ connectionTimeout: 15000 },
|
|
||||||
);
|
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.rws.addEventListener('open', () => {
|
websocketClient
|
||||||
|
.open(`ws://${window.location.host}/ws/chat/${this.props.orderId}/`)
|
||||||
|
.then((connection) => {
|
||||||
console.log('Connected!');
|
console.log('Connected!');
|
||||||
this.setState({ connected: true });
|
|
||||||
this.rws.send(
|
connection.send({
|
||||||
JSON.stringify({
|
|
||||||
type: 'message',
|
|
||||||
message: this.state.own_pub_key,
|
message: this.state.own_pub_key,
|
||||||
nick: this.props.ur_nick,
|
nick: this.props.ur_nick,
|
||||||
}),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.rws.addEventListener('message', (message) => {
|
connection.onMessage(this.onMessage);
|
||||||
|
connection.onClose(() => {
|
||||||
|
console.log('Socket is closed. Reconnect will be attempted');
|
||||||
|
this.setState({ connected: false });
|
||||||
|
});
|
||||||
|
connection.onError(() => {
|
||||||
|
console.error('Socket encountered error: Closing socket');
|
||||||
|
this.setState({ connected: false });
|
||||||
|
});
|
||||||
|
|
||||||
|
this.setState({ connected: true, connection: connection });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate() {
|
||||||
|
// Only fire the scroll and audio when the reason for Update is a new message
|
||||||
|
if (this.state.scrollNow) {
|
||||||
|
const audio = new Audio(`/static/assets/sounds/chat-open.mp3`);
|
||||||
|
audio.play();
|
||||||
|
this.scrollToBottom();
|
||||||
|
this.setState({ scrollNow: false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMessage = (message) => {
|
||||||
const dataFromServer = JSON.parse(message.data);
|
const dataFromServer = JSON.parse(message.data);
|
||||||
console.log('Got reply!', dataFromServer.type);
|
console.log('Got reply!', dataFromServer.type);
|
||||||
console.log(
|
console.log('PGP message index', dataFromServer.index, ' latestIndex ', this.state.latestIndex);
|
||||||
'PGP message index',
|
|
||||||
dataFromServer.index,
|
|
||||||
' latestIndex ',
|
|
||||||
this.state.latestIndex,
|
|
||||||
);
|
|
||||||
if (dataFromServer) {
|
if (dataFromServer) {
|
||||||
console.log(dataFromServer);
|
console.log(dataFromServer);
|
||||||
this.setState({ peer_connected: dataFromServer.peer_connected });
|
this.setState({ peer_connected: dataFromServer.peer_connected });
|
||||||
@ -106,13 +119,10 @@ class Chat extends Component {
|
|||||||
this.setState({ peer_pub_key: dataFromServer.message });
|
this.setState({ peer_pub_key: dataFromServer.message });
|
||||||
|
|
||||||
// After receiving the peer pubkey we ask the server for the historic messages if any
|
// After receiving the peer pubkey we ask the server for the historic messages if any
|
||||||
this.rws.send(
|
this.state.connection.send({
|
||||||
JSON.stringify({
|
|
||||||
type: 'message',
|
|
||||||
message: `-----SERVE HISTORY-----`,
|
message: `-----SERVE HISTORY-----`,
|
||||||
nick: this.props.ur_nick,
|
nick: this.props.ur_nick,
|
||||||
}),
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we receive an encrypted message
|
// If we receive an encrypted message
|
||||||
@ -180,27 +190,7 @@ class Chat extends Component {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
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');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidUpdate() {
|
|
||||||
// Only fire the scroll and audio when the reason for Update is a new message
|
|
||||||
if (this.state.scrollNow) {
|
|
||||||
const audio = new Audio(`/static/assets/sounds/chat-open.mp3`);
|
|
||||||
audio.play();
|
|
||||||
this.scrollToBottom();
|
|
||||||
this.setState({ scrollNow: false });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scrollToBottom = () => {
|
scrollToBottom = () => {
|
||||||
this.messagesEnd.scrollIntoView({ behavior: 'smooth' });
|
this.messagesEnd.scrollIntoView({ behavior: 'smooth' });
|
||||||
@ -217,13 +207,10 @@ class Chat extends Component {
|
|||||||
|
|
||||||
// If input string contains '#' send unencrypted and unlogged message
|
// If input string contains '#' send unencrypted and unlogged message
|
||||||
else if (this.state.value.substring(0, 1) == '#') {
|
else if (this.state.value.substring(0, 1) == '#') {
|
||||||
this.rws.send(
|
this.state.connection.send({
|
||||||
JSON.stringify({
|
|
||||||
type: 'message',
|
|
||||||
message: this.state.value,
|
message: this.state.value,
|
||||||
nick: this.props.ur_nick,
|
nick: this.props.ur_nick,
|
||||||
}),
|
});
|
||||||
);
|
|
||||||
this.setState({ value: '' });
|
this.setState({ value: '' });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,13 +226,10 @@ class Chat extends Component {
|
|||||||
).then(
|
).then(
|
||||||
(encryptedMessage) =>
|
(encryptedMessage) =>
|
||||||
console.log('Sending Encrypted MESSAGE', encryptedMessage) &
|
console.log('Sending Encrypted MESSAGE', encryptedMessage) &
|
||||||
this.rws.send(
|
this.state.connection.send({
|
||||||
JSON.stringify({
|
|
||||||
type: 'message',
|
|
||||||
message: encryptedMessage.split('\n').join('\\'),
|
message: encryptedMessage.split('\n').join('\\'),
|
||||||
nick: this.props.ur_nick,
|
nick: this.props.ur_nick,
|
||||||
}),
|
}),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
import ReconnectingWebSocket from 'reconnecting-websocket';
|
||||||
|
import { WebsocketConnection } from '..';
|
||||||
|
|
||||||
|
class WebsocketConnectionWeb implements WebsocketConnection {
|
||||||
|
constructor(path: string) {
|
||||||
|
this.rws = new ReconnectingWebSocket(path, [], { connectionTimeout: 15000 });
|
||||||
|
}
|
||||||
|
|
||||||
|
public rws: ReconnectingWebSocket;
|
||||||
|
|
||||||
|
public send: (message: object) => void = (message: object) => {
|
||||||
|
this.rws.send(
|
||||||
|
JSON.stringify({
|
||||||
|
type: 'message',
|
||||||
|
...message,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
public onMessage: (event: (message: object) => void) => void = (event) => {
|
||||||
|
this.rws.addEventListener('message', event);
|
||||||
|
};
|
||||||
|
|
||||||
|
public onClose: (event: () => void) => void = (event) => {
|
||||||
|
this.rws.addEventListener('close', event);
|
||||||
|
};
|
||||||
|
|
||||||
|
public onError: (event: () => void) => void = (event) => {
|
||||||
|
this.rws.addEventListener('error', event);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default WebsocketConnectionWeb;
|
19
frontend/src/services/Websocket/WebsocketWebClient/index.ts
Normal file
19
frontend/src/services/Websocket/WebsocketWebClient/index.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { WebsocketClient, WebsocketConnection } from '..';
|
||||||
|
import WebsocketConnectionWeb from '../WebsocketConnectionWeb';
|
||||||
|
|
||||||
|
class WebsocketWebClient implements WebsocketClient {
|
||||||
|
public open: (path: string) => Promise<WebsocketConnection> = (path) => {
|
||||||
|
return new Promise<WebsocketConnection>((resolve, reject) => {
|
||||||
|
try {
|
||||||
|
const connection = new WebsocketConnectionWeb(path);
|
||||||
|
connection.rws.addEventListener('open', () => {
|
||||||
|
resolve(connection);
|
||||||
|
});
|
||||||
|
} catch {
|
||||||
|
reject();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default WebsocketWebClient;
|
14
frontend/src/services/Websocket/index.ts
Normal file
14
frontend/src/services/Websocket/index.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import WebsocketWebClient from './WebsocketWebClient';
|
||||||
|
|
||||||
|
export interface WebsocketConnection {
|
||||||
|
send: (message: object) => void;
|
||||||
|
onMessage: (event: (message: object) => void) => void;
|
||||||
|
onClose: (event: () => void) => void;
|
||||||
|
onError: (event: () => void) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface WebsocketClient {
|
||||||
|
open: (path: string) => Promise<WebsocketConnection>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const websocketClient: WebsocketClient = new WebsocketWebClient();
|
Reference in New Issue
Block a user