diff --git a/web-chat/src/App.tsx b/web-chat/src/App.tsx index 7f09b2b4bb..1dd796a55f 100644 --- a/web-chat/src/App.tsx +++ b/web-chat/src/App.tsx @@ -1,6 +1,6 @@ import React from 'react'; import './App.css'; -import Log from './Log'; +import Room from './Room'; interface Props { } @@ -21,8 +21,8 @@ class App extends React.Component { render() { return (
-
- +
+
); diff --git a/web-chat/src/Log.tsx b/web-chat/src/Room.tsx similarity index 69% rename from web-chat/src/Log.tsx rename to web-chat/src/Room.tsx index cead27f6f9..731aa74821 100644 --- a/web-chat/src/Log.tsx +++ b/web-chat/src/Room.tsx @@ -7,10 +7,10 @@ interface Props { interface State { } -export default class Log extends React.Component { +export default class Room extends React.Component { render() { return ( -
+
{this.renderLines(this.props.lines)}
); @@ -20,7 +20,7 @@ export default class Log extends React.Component { const renderedLines = []; for (const line of lines) { - renderedLines.push(
{line}
); + renderedLines.push(
{line}
); } return ( diff --git a/web-chat/src/WakuMock.test.ts b/web-chat/src/WakuMock.test.ts new file mode 100644 index 0000000000..c5dc6640f7 --- /dev/null +++ b/web-chat/src/WakuMock.test.ts @@ -0,0 +1,30 @@ +import WakuMock, { Message } from './WakuMock'; + +test('Messages are emitted', async () => { + const wakuMock = await WakuMock.create(); + + let message: Message; + wakuMock.on('message', (msg) => { + message = msg; + }); + + await new Promise((resolve) => setTimeout(resolve, 2000)); + // @ts-ignore + expect(message.message).toBeDefined(); +}); + +test('Messages are sent', async () => { + const wakuMock = await WakuMock.create(); + + const text = 'This is a message.'; + + let message: Message; + wakuMock.on('message', (msg) => { + message = msg; + }); + + await wakuMock.send(text); + + // @ts-ignore + expect(message.message).toEqual(text); +}); diff --git a/web-chat/src/WakuMock.ts b/web-chat/src/WakuMock.ts new file mode 100644 index 0000000000..9bb2cbdaca --- /dev/null +++ b/web-chat/src/WakuMock.ts @@ -0,0 +1,71 @@ +class EventEmitter { + public callbacks: { [key: string]: Array<(data: T) => void> }; + + constructor() { + this.callbacks = {}; + } + + on(event: string, cb: (data: T) => void) { + if (!this.callbacks[event]) this.callbacks[event] = []; + this.callbacks[event].push(cb); + } + + emit(event: string, data: T) { + let cbs = this.callbacks[event]; + if (cbs) { + cbs.forEach(cb => cb(data)); + } + } +} + + +export interface Message { + timestamp: Date; + handle: string; + message: string; +} + +export default class WakuMock extends EventEmitter { + index: number; + intervalId?: number | NodeJS.Timeout; + + private constructor() { + super(); + this.index = 0; + } + + public static async create(): Promise { + await new Promise((resolve) => setTimeout(resolve, 1000)); + + const wakuMock = new WakuMock(); + wakuMock.startInterval(); + return wakuMock; + } + + public async send(message: string): Promise { + const timestamp = new Date(); + const handle = 'me'; + this.emit('message', { + timestamp, + handle, + message + }); + } + + private startInterval() { + if (this.intervalId === undefined) { + this.intervalId = setInterval(this.emitMessage.bind(this), 1000); + } + } + + private emitMessage() { + const handle = 'you'; + const timestamp = new Date(); + this.emit('message', { + timestamp, + handle, + message: `This is message #${this.index++}.` + }); + } +} + diff --git a/web-chat/src/index.css b/web-chat/src/index.css index b6e43f80b0..a6cbaec0da 100644 --- a/web-chat/src/index.css +++ b/web-chat/src/index.css @@ -12,12 +12,12 @@ code { monospace; } -.log-row { +.room-row { text-align: left; margin-left: 20px; } -.log-row:after { +.room-row:after { clear: both; content: ""; display: table;