diff --git a/components/app.js b/components/app.js
index 4985d74..0a4be12 100644
--- a/components/app.js
+++ b/components/app.js
@@ -865,13 +865,46 @@ export default class App extends Component {
this.connect(connectParams);
}
- handleChannelClick(channel) {
- let serverID = State.getActiveServerID(this.state);
- let buf = State.getBuffer(this.state, { server: serverID, name: channel });
+ handleChannelClick(event) {
+ let url = irc.parseURL(event.target.href);
+ if (!url) {
+ return;
+ }
+
+ let serverID;
+ if (!url.host) {
+ serverID = State.getActiveServerID(this.state);
+ } else {
+ let bouncerNetID;
+ for (let [id, bouncerNetwork] of this.state.bouncerNetworks) {
+ if (bouncerNetwork.host === url.host) {
+ bouncerNetID = id;
+ break;
+ }
+ }
+ if (!bouncerNetID) {
+ // TODO: open dialog to create network if bouncer
+ return;
+ }
+
+ for (let [id, server] of this.state.servers) {
+ if (server.isupport.get("BOUNCER_NETID") === bouncerNetID) {
+ serverID = id;
+ break;
+ }
+ }
+ }
+ if (!serverID) {
+ return;
+ }
+
+ event.preventDefault();
+
+ let buf = State.getBuffer(this.state, { server: serverID, name: url.channel });
if (buf) {
this.switchBuffer(buf.id);
} else {
- this.open(channel);
+ this.open(url.channel, serverID);
}
}
diff --git a/lib/irc.js b/lib/irc.js
index f1f0817..95b7860 100644
--- a/lib/irc.js
+++ b/lib/irc.js
@@ -656,3 +656,27 @@ export function isMeaningfulRealname(realname, nick) {
return true;
}
+
+export function parseURL(str) {
+ if (!str.startsWith("irc://") && !str.startsWith("ircs://")) {
+ return null;
+ }
+
+ str = str.slice(str.indexOf(":") + 3);
+
+ let i = str.indexOf("/");
+ if (i < 0) {
+ return null;
+ }
+
+ let host = str.slice(0, i);
+ str = str.slice(i + 1);
+
+ // TODO: handle URLs with query params
+ if (!str.startsWith("#")) {
+ return null;
+ }
+ let channel = str;
+
+ return { host, channel };
+}
diff --git a/lib/linkify.js b/lib/linkify.js
index b8623fe..6004a31 100644
--- a/lib/linkify.js
+++ b/lib/linkify.js
@@ -5,11 +5,11 @@ linkifyjs.options.defaults.defaultProtocol = "https";
linkifyjs.registerCustomProtocol("irc");
linkifyjs.registerCustomProtocol("ircs");
-linkifyjs.registerPlugin('ircChannel', ({ scanner, parser, utils }) => {
+linkifyjs.registerPlugin("ircChannel", ({ scanner, parser, utils }) => {
const { POUND, DOMAIN, TLD, LOCALHOST, UNDERSCORE, DOT, HYPHEN } = scanner.tokens;
const START_STATE = parser.start;
- const Channel = utils.createTokenClass('ircChannel', {
+ const Channel = utils.createTokenClass("ircChannel", {
isLink: true,
toHref() {
return "irc:///" + this.toString();
@@ -36,7 +36,7 @@ linkifyjs.registerPlugin('ircChannel', ({ scanner, parser, utils }) => {
CHAN_DIVIDER_STATE.tt(LOCALHOST, CHAN_STATE);
});
-export default function linkify(text, onChannelClick) {
+export default function linkify(text, onClick) {
let links = linkifyjs.find(text);
let children = [];
@@ -49,27 +49,14 @@ export default function linkify(text, onChannelClick) {
const prefix = text.substring(last, match.start)
children.push(prefix);
- // TODO: handle all irc/ircs URLs
- if (match.href.startsWith("irc:///")) {
- function onClick(event) {
- event.preventDefault();
- onChannelClick(match.value);
- }
- children.push(html`
- ${match.value}
- `);
- } else {
- children.push(html`
- ${match.value}
- `);
- }
+ children.push(html`
+ ${match.value}
+ `);
last = match.end;
});