UNPKG

@mothepro/fancy-p2p

Version:

A quick and efficient way to form p2p groups in the browser

116 lines (115 loc) 4.75 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; import { LitElement, html, customElement, property, internalProperty } from 'lit-element'; let default_1 = class default_1 extends LitElement { constructor() { super(...arguments); /** Others connected to the lobby. */ this.clients = []; /** List of incoming proposals */ this.proposals = []; this.log = (...detail) => this.dispatchEvent(new CustomEvent('log', { detail, bubbles: true, composed: true })) && this.requestUpdate(); /** Chilling in the lobby. */ this.render = () => html `${this.clients.length ? html ` Clients connected to this lobby <form @submit=${(event) => // Propose group of all the ack'd clients this.dispatchEvent(new CustomEvent('proposeGroup', { detail: this.clients .filter(({ ack }) => ack) .map(({ client }) => client) })) && event.preventDefault()}} > <ul id="others"> ${[...this.clients].map(({ client: { name, isYou }, ack }, index) => html ` <li> <label> <input type="checkbox" ?checked=${ack} ?disabled=${isYou} @click=${() => this.clients = this.clients.map(({ client, ack: currentAck }, i) => ({ client, ack: index == i ? !currentAck : currentAck, }))} /> ${name} </label> </li>`)} </ul> <input type="submit" value="Propose Group" ?disabled=${!this.clients.some(({ ack }) => ack)} /> </form> ${this.proposals.map(({ groupName, action }, index) => html ` Join group with ${groupName}? <button @click=${() => { this.proposals = this.proposals.filter((_, i) => index != i); action(true); }}>Accept</button> <button @click=${() => { this.proposals = this.proposals.filter((_, i) => index != i); action(false); }}>Reject</button> <br/>`)}` : 'No one else has joined this lobby... yet.'}`; } async firstUpdated() { for await (const client of this.connection) { this.clients = [...this.clients, { client, ack: false }]; this.log(`${client.name} has joined the lobby`); this.bindProposals(client); } } async bindProposals(client) { for await (const { members, ack, action } of client.proposals) { const names = members.map(({ name }) => name).join(', '); this.log(`${client.isYou ? 'You' : client.name} proposed a group for ${names} & you`); this.bindAck(names, ack, action); } this.clients = this.clients.filter(({ client: currentClient }) => currentClient != client); this.log(`${client.name} has left the lobby`); } async bindAck(groupName, ack, action) { const current = this.proposals.length; // the index of the proposal we may add if (action) // proposal that we can accept or reject this.proposals = [...this.proposals, { groupName, action }]; try { for await (const { name } of ack) this.log(`${name} accepted invitation with ${groupName} & you`); } catch (err) { this.log(err.client ? `${err.client.name} rejected invitation to group with ${groupName} & you` : `Group with ${groupName} & you was shut down`, err); } finally { // Remove the proposal once it is completed. if (action) this.proposals = this.proposals.filter((_, i) => current != i); } } }; __decorate([ property({ attribute: false }) ], default_1.prototype, "connection", void 0); __decorate([ internalProperty() ], default_1.prototype, "clients", void 0); __decorate([ internalProperty() ], default_1.prototype, "proposals", void 0); default_1 = __decorate([ customElement('lit-lobby') ], default_1); export default default_1; //# sourceMappingURL=lobby.js.map