diff --git a/components/app.js b/components/app.js index 468157c..a85aa5e 100644 --- a/components/app.js +++ b/components/app.js @@ -909,11 +909,11 @@ export default class App extends Component { event.preventDefault(); - let buf = State.getBuffer(this.state, { server: serverID, name: url.channel || SERVER_BUFFER }); + let buf = State.getBuffer(this.state, { server: serverID, name: url.entity || SERVER_BUFFER }); if (buf) { this.switchBuffer(buf.id); } else { - this.open(url.channel, serverID); + this.open(url.entity, serverID); } } diff --git a/lib/irc.js b/lib/irc.js index 2286fcb..601e67e 100644 --- a/lib/irc.js +++ b/lib/irc.js @@ -648,6 +648,8 @@ export function forEachChannelModeUpdate(msg, isupport, callback) { } /** + * Check if a realname is worth displaying. + * * Since the realname is mandatory, many clients set a meaningless realname. */ export function isMeaningfulRealname(realname, nick) { @@ -664,26 +666,60 @@ export function isMeaningfulRealname(realname, nick) { return true; } +/* Parse an irc:// URL. + * + * See: https://datatracker.ietf.org/doc/html/draft-butcher-irc-url-04 + */ export function parseURL(str) { if (!str.startsWith("irc://") && !str.startsWith("ircs://")) { return null; } - str = str.slice(str.indexOf(":") + 3); + str = str.slice(str.indexOf(":") + "://".length); + let loc; let i = str.indexOf("/"); if (i < 0) { - return { host: str }; + loc = str; + str = ""; + } else { + loc = str.slice(0, i); + str = str.slice(i + 1); } - let host = str.slice(0, i); - str = str.slice(i + 1); - - // TODO: handle URLs with query params - let channel = null; - if (str.startsWith("#")) { - channel = str; + let host = loc; + i = loc.indexOf("@"); + if (i >= 0) { + host = loc.slice(i + 1); + // TODO: parse authinfo } - return { host, channel }; + i = str.indexOf("?"); + if (i >= 0) { + str = str.slice(0, i); + // TODO: parse options + } + + let enttype; + i = str.indexOf(","); + if (i >= 0) { + let flags = str.slice(i + 1).split(","); + str = str.slice(0, i); + + if (flags.indexOf("isuser") >= 0) { + enttype = "user"; + } else if (flags.indexOf("ischannel") >= 0) { + enttype = "channel"; + } + + // TODO: parse hosttype + } + + let entity = decodeURIComponent(str); + if (!enttype) { + // TODO: technically we should use the PREFIX ISUPPORT here + enttype = entity.startsWith("#") ? "channel" : "user"; + } + + return { host, enttype, entity }; }