diff --git a/components/app.js b/components/app.js index 74544b8..9657692 100644 --- a/components/app.js +++ b/components/app.js @@ -542,19 +542,19 @@ export default class App extends Component { } } + networkFromBouncerNetwork(bouncerNetworkID) { + for (var [id, client] of this.clients) { + if (client.params.bouncerNetwork === bouncerNetworkID) { + return id; + } + } + return null; + } + handleMessage(netID, msg) { var client = this.clients.get(netID); switch (msg.command) { case irc.RPL_WELCOME: - if (client.enabledCaps["soju.im/bouncer-networks"] && !client.params.bouncerNetwork) { - client.listBouncerNetworks().then((bouncerNetworks) => { - this.setState((state) => { - return { bouncerNetworks }; - }); - this.openSecondaryClients(client, bouncerNetworks); - }); - } - if (this.state.connectParams.autojoin.length > 0) { client.send({ command: "JOIN", @@ -745,11 +745,47 @@ export default class App extends Component { this.setState({ error: description }); this.addMessage(netID, SERVER_BUFFER, msg); break; + case "BOUNCER": + if (msg.params[0] !== "NETWORK") { + break; // We're only interested in network updates + } + + var id = msg.params[1]; + var attrs = null; + if (msg.params[2] !== "*") { + attrs = irc.parseTags(msg.params[2]); + } + + var isNew = false; + this.setState((state) => { + var bouncerNetworks = new Map(state.bouncerNetworks); + if (!attrs) { + bouncerNetworks.delete(id); + } else { + var prev = bouncerNetworks.get(id); + isNew = prev === undefined; + attrs = { ...prev, ...attrs }; + bouncerNetworks.set(id, attrs); + } + return { bouncerNetworks }; + }, () => { + if (!attrs) { + var netID = this.networkFromBouncerNetwork(id); + if (netID) { + this.close({ network: netID, name: SERVER_BUFFER }); + } + } else if (isNew) { + this.connect({ + ...client.params, + bouncerNetwork: id, + }); + } + }); + break; case "CAP": case "AUTHENTICATE": case "PING": case "BATCH": - case "BOUNCER": // Ignore these break; default: @@ -757,15 +793,6 @@ export default class App extends Component { } } - openSecondaryClients(client, bouncerNetworks) { - bouncerNetworks.forEach((attrs, id) => { - this.connect({ - ...client.params, - bouncerNetwork: id, - }); - }); - } - handleConnectSubmit(connectParams) { this.setState({ error: null }); diff --git a/lib/client.js b/lib/client.js index 81809dc..48ff69d 100644 --- a/lib/client.js +++ b/lib/client.js @@ -308,6 +308,10 @@ export default class Client extends EventTarget { capEnd = false; } + if (!this.params.bouncerNetwork && this.availableCaps["soju.im/bouncer-networks-notify"] !== undefined) { + reqCaps.push("soju.im/bouncer-networks-notify"); + } + this.requestCaps(reqCaps); if (this.status != Client.Status.REGISTERED && capEnd) {