~emersion/public-inbox

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch

[PATCH gamja v2] Linkify channel names

Details
Message ID
<20210601022310.2471449-1-me@tomlebreux.com>
DKIM signature
pass
Download raw message
Patch: +66 -9
---
Fixed issues from v1.

For channel name regex, I added a TODO. A possible option would be to
match on ([\w-_]+).

Curious, why using function(){} instead of const .. = () => {}
construct?
 components/app.js           | 17 ++++++++++++++-
 components/buffer-header.js |  2 +-
 components/buffer.js        | 14 +++++++++----
 lib/linkify.js              | 42 ++++++++++++++++++++++++++++++++++---
 4 files changed, 66 insertions(+), 9 deletions(-)

diff --git a/components/app.js b/components/app.js
index 38d3cb46cc9b..8ce304b7aee9 100644
--- a/components/app.js
+++ b/components/app.js
@@ -197,6 +197,7 @@ export default class App extends Component {
		this.toggleBufferList = this.toggleBufferList.bind(this);
		this.toggleMemberList = this.toggleMemberList.bind(this);
		this.handleComposerSubmit = this.handleComposerSubmit.bind(this);
		this.handleChannelClick = this.handleChannelClick.bind(this);
		this.handleNickClick = this.handleNickClick.bind(this);
		this.autocomplete = this.autocomplete.bind(this);
		this.handleBufferScrollTop = this.handleBufferScrollTop.bind(this);
@@ -891,6 +892,16 @@ export default class App extends Component {
		this.connect(connectParams);
	}

	handleChannelClick(channel) {
		var netID = getActiveNetworkID(this.state);
		var buf = getBuffer(this.state, { network: netID, name: channel });
		if (buf) {
			this.switchBuffer(buf.id);
		} else {
			this.open(channel);
		}
	}

	handleNickClick(nick) {
		this.open(nick);
	}
@@ -1261,6 +1272,7 @@ export default class App extends Component {
						network=${activeNetwork}
						isBouncer=${isBouncer}
						bouncerNetwork=${activeBouncerNetwork}
						onChannelClick=${this.handleChannelClick}
						onClose=${() => this.close(activeBuffer)}
						onJoin=${() => this.handleJoinClick(activeBuffer.network)}
						onAddNetwork=${this.handleAddNetworkClick}
@@ -1367,7 +1379,10 @@ export default class App extends Component {
				onScrollTop=${this.handleBufferScrollTop}
			>
				<section id="buffer" ref=${this.buffer}>
					<${Buffer} buffer=${activeBuffer} onNickClick=${this.handleNickClick}/>
					<${Buffer}
						buffer=${activeBuffer}
						onChannelClick=${this.handleChannelClick}
						onNickClick=${this.handleNickClick}/>
				</section>
			</>
			${memberList}
diff --git a/components/buffer-header.js b/components/buffer-header.js
index 62c80651bd42..28f134bab659 100644
--- a/components/buffer-header.js
+++ b/components/buffer-header.js
@@ -70,7 +70,7 @@ export default function BufferHeader(props) {
			break;
		}
	} else if (props.buffer.topic) {
		description = linkify(stripANSI(props.buffer.topic));
		description = linkify(stripANSI(props.buffer.topic), props.onChannelClick);
	} else if (props.buffer.who) {
		var who = props.buffer.who;

diff --git a/components/buffer.js b/components/buffer.js
index b92e5805bbf2..e6962e0e9864 100644
--- a/components/buffer.js
+++ b/components/buffer.js
@@ -47,6 +47,7 @@ class LogLine extends Component {
	render() {
		var msg = this.props.message;

		var onChannelClick = this.props.onChannelClick;
		var onNickClick = this.props.onNickClick;
		function createNick(nick) {
			return html`
@@ -65,7 +66,7 @@ class LogLine extends Component {
			if (ctcp) {
				if (ctcp.command == "ACTION") {
					lineClass = "me-tell";
					content = html`* ${createNick(msg.prefix.name)} ${linkify(stripANSI(ctcp.param))}`;
					content = html`* ${createNick(msg.prefix.name)} ${linkify(stripANSI(ctcp.param), onChannelClick)}`;
				} else {
					content = html`
						${createNick(msg.prefix.name)} has sent a CTCP command: ${ctcp.command} ${ctcp.param}
@@ -77,7 +78,7 @@ class LogLine extends Component {
				if (msg.command == "NOTICE") {
					prefix = suffix = "-";
				}
				content = html`${prefix}${createNick(msg.prefix.name)}${suffix} ${linkify(stripANSI(text))}`;
				content = html`${prefix}${createNick(msg.prefix.name)}${suffix} ${linkify(stripANSI(text), onChannelClick)}`;
			}

			if (msg.isHighlight) {
@@ -118,7 +119,7 @@ class LogLine extends Component {
		case "TOPIC":
			var topic = msg.params[1];
			content = html`
				${createNick(msg.prefix.name)} changed the topic to: ${linkify(stripANSI(topic))}
				${createNick(msg.prefix.name)} changed the topic to: ${linkify(stripANSI(topic), onChannelClick)}
			`;
			break;
		case irc.RPL_MOTD:
@@ -242,7 +243,12 @@ export default class Buffer extends Component {
			prevDate = date;

			children.push(html`
				<${LogLine} key=${"msg-" + msg.key} message=${msg} buffer=${buf} onNickClick=${this.props.onNickClick}/>
				<${LogLine}
					key=${"msg-" + msg.key}
					message=${msg}
					buffer=${buf}
					onChannelClick=${this.props.onChannelClick}
					onNickClick=${this.props.onNickClick}/>
			`);
		});

diff --git a/lib/linkify.js b/lib/linkify.js
index c9697cd1bd4a..aee4512a134d 100644
--- a/lib/linkify.js
+++ b/lib/linkify.js
@@ -1,12 +1,46 @@
import { anchorme, html } from "./index.js";

export default function linkify(text) {
function linkifyChannel(text, transformChannel) {
	var children = [];
	// TODO: Don't match punctuation
	const channelRegex = /(^|\s)(#[^\s]+)/gid;
	let match;

	var last = 0;
	while ((match = channelRegex.exec(text)) !== null) {
		const [_, spaces, channel] = match;

		const start = match.index + spaces.length;
		children.push(text.substring(last, start));
		children.push(transformChannel(channel));

		last = match.index + spaces.length + channel.length;
	}
	children.push(text.substring(last));

	return children;
}

export default function linkify(text, onChannelClick) {
	function transformChannel(channel) {
		function onClick(event) {
			event.preventDefault();
			onChannelClick(channel);
		}
		return html`
			<a
				href="irc:///${encodeURIComponent(channel)}"
				onClick=${onClick}
			>${channel}</a>`;
	}

	var links = anchorme.list(text);

	var children = [];
	var last = 0;
	links.forEach((match) => {
		children.push(text.substring(last, match.start));
		const prefix = text.substring(last, match.start)
		children.push(...linkifyChannel(prefix, transformChannel));

		var proto = match.protocol || "https://";
		if (match.isEmail) {
@@ -22,7 +56,9 @@ export default function linkify(text) {

		last = match.end;
	});
	children.push(text.substring(last));

	const suffix = text.substring(last)
	children.push(...linkifyChannel(suffix, transformChannel));

	return children;
}
-- 
2.31.1
Reply to thread Export thread (mbox)