mirror of
https://codeberg.org/emersion/gamja
synced 2025-03-13 07:48:37 +01:00
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
24
lib/irc.js
24
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 };
|
||||
}
|
||||
|
@ -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`
|
||||
<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>
|
||||
`);
|
||||
}
|
||||
children.push(html`
|
||||
<a
|
||||
href=${match.href}
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
onClick=${onClick}
|
||||
>${match.value}</a>
|
||||
`);
|
||||
|
||||
last = match.end;
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user