Commit d7678145 authored by Tomáš Hübelbauer's avatar Tomáš Hübelbauer

Implement DOM EventTarget for Channel and Peer

parent ebe6fa55
......@@ -3,6 +3,7 @@ import * as qrcode_ from 'qrcode-generator';
import Message from './Message';
import Peer from './Peer';
import ReadReceipt from './ReadReceipt';
import EventTarget from './EventTarget';
const jsQR: typeof jsQR_.default = jsQR_ as any;
const qrcode: typeof qrcode_ = qrcode_;
......@@ -21,8 +22,17 @@ type Mode = 'Numeric' | 'Alphanumeric' | 'Byte' /* Default */;
type SentMessage = { message: string; messageNumber: number; recipientName: string | null; };
type PeerEventHandler = (event: PeerEvent) => void;
class PeerEvent extends Event {
public readonly peerName: Peer;
constructor(peerName: Peer) {
super('peer');
this.peerName = peerName;
}
}
// TODO: Make this an event emitter.
export default class Channel {
export default class Channel extends EventTarget {
public static readonly SCANNING_TIMEOUT_MS = 25;
public static readonly CYCLING_TIMEOUT_MS = 25;
public static readonly MESSAGE_PAYLOAD_SIZE = 40;
......@@ -48,6 +58,7 @@ export default class Channel {
private cyclingHandle: number | undefined;
constructor(name: string, viewfinderVideo: HTMLVideoElement, snapshotCanvas: HTMLCanvasElement, codeCanvas: HTMLCanvasElement) {
super();
this.name = name;
this.viewfinderVideo = viewfinderVideo;
......@@ -59,6 +70,9 @@ export default class Channel {
this.cycle = this.cycle.bind(this);
}
public addEventListener(type: 'peer', listener: PeerEventHandler | EventListenerObject | undefined): void;
public addEventListener(type: string, listener: EventListener | EventListenerObject) { super.addEventListener(type, listener as EventListener); }
/**
* Initiates periodical scanning of the webcam stream for QR codes for processing.
*/
......@@ -172,7 +186,7 @@ export default class Channel {
if (peer === undefined) {
peer = new Peer(message.senderName); // TODO: Pass the `cast` promise here.
this.peers.push(peer);
// TODO: Emit a `peer(name)` event instance.
this.dispatchEvent(new PeerEvent(peer));
}
if (message.readReceipt !== null) {
......
// https://developer.mozilla.org/en-US/docs/Web/API/EventTarget
export default class implements EventTarget {
listeners: { [type: string]: (EventListener | EventListenerObject)[]; } = {};
public addEventListener(type: string, listener?: EventListener | EventListenerObject | undefined, options?: boolean | AddEventListenerOptions | undefined): void {
if (listener === undefined) {
return;
}
if (!(type in this.listeners)) {
this.listeners[type] = [];
}
this.listeners[type].push(listener);
}
public removeEventListener(type: string, listener?: EventListener | EventListenerObject | undefined, options?: boolean | EventListenerOptions | undefined): void {
if (listener === undefined) {
return;
}
if (!(type in this.listeners)) {
return;
}
var stack = this.listeners[type];
for (var i = 0, l = stack.length; i < l; i++) {
if (stack[i] === listener){
stack.splice(i, 1);
return;
}
}
}
public dispatchEvent(evt: Event): boolean {
if (!(evt.type in this.listeners)) {
return true;
}
var stack = this.listeners[evt.type];
for (var i = 0, l = stack.length; i < l; i++) {
if (stack[i].hasOwnProperty('handleEvent')) {
(stack[i] as EventListenerObject).handleEvent(evt);
} else {
(stack[i] as EventListener).call(this, evt);
}
}
return !evt.defaultPrevented;
}
}
import EventTarget from './EventTarget';
type ReceivedMessage = { number: number; chunkCount: number; chunks: string[]; };
type ChunkSentEventHandler = (event: ChunkSentEvent) => void;
class ChunkSentEvent extends Event {
constructor() {
super('chunkSent');
}
}
type ChunkReceivedEventHandler = (event: ChunkReceivedEvent) => void;
class ChunkReceivedEvent extends Event {
constructor() {
super('chunkReceived');
}
}
type MessageEventHandler = (event: MessageEvent) => void;
class MessageEvent extends Event {
constructor() {
super('message');
}
}
// TODO: Make this an event emitter.
export default class QrPeer {
export default class Peer extends EventTarget {
public readonly name: string;
public readonly receivedMessages: ReceivedMessage[] = [];
constructor(name: string) {
super();
this.name = name;
}
public addEventListener(type: 'chunkSent', listener: ChunkSentEventHandler | EventListenerObject | undefined): void;
public addEventListener(type: 'chunkReceived', listener: ChunkReceivedEventHandler | EventListenerObject | undefined): void;
public addEventListener(type: 'message', listener: MessageEventHandler | EventListenerObject | undefined): void;
public addEventListener(type: string, listener: EventListener | EventListenerObject) { super.addEventListener(type, listener); }
public feed(messageNumber: number, messageChunkNumber: number, messageChunkCount: number, payload: string) {
let message = this.receivedMessages.find(m => m.number === messageNumber);
if (!message) {
......
# Implement the event emitter pattern
For `Channel` and `Peer`.
Packages:
- [event-emitter](https://www.npmjs.com/package/event-emitter)
- [event-emitter-es6](https://www.npmjs.com/package/event-emitter-es6)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment