forked from CringeStudios/gamja
Handle click on irc:// channel URLs inside buffers
References: https://todo.sr.ht/~emersion/gamja/71
This commit is contained in:
parent
631f119061
commit
405bc51c26
@ -865,13 +865,46 @@ export default class App extends Component {
|
|||||||
this.connect(connectParams);
|
this.connect(connectParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleChannelClick(channel) {
|
handleChannelClick(event) {
|
||||||
let serverID = State.getActiveServerID(this.state);
|
let url = irc.parseURL(event.target.href);
|
||||||
let buf = State.getBuffer(this.state, { server: serverID, name: channel });
|
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) {
|
if (buf) {
|
||||||
this.switchBuffer(buf.id);
|
this.switchBuffer(buf.id);
|
||||||
} else {
|
} else {
|
||||||
this.open(channel);
|
this.open(url.channel, serverID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
24
lib/irc.js
24
lib/irc.js
@ -656,3 +656,27 @@ export function isMeaningfulRealname(realname, nick) {
|
|||||||
|
|
||||||
return true;
|
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 };
|
||||||
|
}
|
||||||
|
@ -5,11 +5,11 @@ linkifyjs.options.defaults.defaultProtocol = "https";
|
|||||||
linkifyjs.registerCustomProtocol("irc");
|
linkifyjs.registerCustomProtocol("irc");
|
||||||
linkifyjs.registerCustomProtocol("ircs");
|
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 { POUND, DOMAIN, TLD, LOCALHOST, UNDERSCORE, DOT, HYPHEN } = scanner.tokens;
|
||||||
const START_STATE = parser.start;
|
const START_STATE = parser.start;
|
||||||
|
|
||||||
const Channel = utils.createTokenClass('ircChannel', {
|
const Channel = utils.createTokenClass("ircChannel", {
|
||||||
isLink: true,
|
isLink: true,
|
||||||
toHref() {
|
toHref() {
|
||||||
return "irc:///" + this.toString();
|
return "irc:///" + this.toString();
|
||||||
@ -36,7 +36,7 @@ linkifyjs.registerPlugin('ircChannel', ({ scanner, parser, utils }) => {
|
|||||||
CHAN_DIVIDER_STATE.tt(LOCALHOST, CHAN_STATE);
|
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 links = linkifyjs.find(text);
|
||||||
|
|
||||||
let children = [];
|
let children = [];
|
||||||
@ -49,27 +49,14 @@ export default function linkify(text, onChannelClick) {
|
|||||||
const prefix = text.substring(last, match.start)
|
const prefix = text.substring(last, match.start)
|
||||||
children.push(prefix);
|
children.push(prefix);
|
||||||
|
|
||||||
// TODO: handle all irc/ircs URLs
|
children.push(html`
|
||||||
if (match.href.startsWith("irc:///")) {
|
<a
|
||||||
function onClick(event) {
|
href=${match.href}
|
||||||
event.preventDefault();
|
target="_blank"
|
||||||
onChannelClick(match.value);
|
rel="noreferrer noopener"
|
||||||
}
|
onClick=${onClick}
|
||||||
children.push(html`
|
>${match.value}</a>
|
||||||
<a
|
`);
|
||||||
href="${match.href}"
|
|
||||||
onClick=${onClick}
|
|
||||||
>${match.value}</a>
|
|
||||||
`);
|
|
||||||
} else {
|
|
||||||
children.push(html`
|
|
||||||
<a
|
|
||||||
href=${match.href}
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer noopener"
|
|
||||||
>${match.value}</a>
|
|
||||||
`);
|
|
||||||
}
|
|
||||||
|
|
||||||
last = match.end;
|
last = match.end;
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user