From c05af5bb6d4f801f92305ed9cd40ec9bafce0c90 Mon Sep 17 00:00:00 2001
From: Simon Ser <contact@emersion.fr>
Date: Thu, 25 Jun 2020 18:45:41 +0200
Subject: [PATCH] Make nick links clickable

---
 components/app.js    | 23 ++++++++++++++++++++++-
 components/buffer.js | 22 ++++++++++++++--------
 2 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/components/app.js b/components/app.js
index c2275e6..500b935 100644
--- a/components/app.js
+++ b/components/app.js
@@ -48,6 +48,7 @@ export default class App extends Component {
 		this.handleConnectSubmit = this.handleConnectSubmit.bind(this);
 		this.handleBufferListClick = this.handleBufferListClick.bind(this);
 		this.handleComposerSubmit = this.handleComposerSubmit.bind(this);
+		this.handleNickClick = this.handleNickClick.bind(this);
 
 		if (window.localStorage && localStorage.getItem("autoconnect")) {
 			var connectParams = JSON.parse(localStorage.getItem("autoconnect"));
@@ -310,11 +311,23 @@ export default class App extends Component {
 		this.connect(connectParams);
 	}
 
+	handleNickClick(nick) {
+		this.open(nick);
+	}
+
 	isChannel(name) {
 		// TODO: use the ISUPPORT token if available
 		return irc.STD_CHANNEL_TYPES.indexOf(name[0]) >= 0;
 	}
 
+	open(target) {
+		if (this.isChannel(target)) {
+			this.client.send({ command: "JOIN", params: [target] });
+		}
+		this.createBuffer(target);
+		this.switchBuffer(target);
+	}
+
 	close(target) {
 		if (target == SERVER_BUFFER) {
 			this.client.close();
@@ -342,6 +355,14 @@ export default class App extends Component {
 			}
 			this.client.close();
 			break;
+		case "query":
+			var nick = args[0];
+			if (!nick) {
+				console.error("Missing nickname");
+				return;
+			}
+			this.open(nick);
+			break;
 		case "close":
 			var target = this.state.activeBuffer;
 			if (!target || target == SERVER_BUFFER) {
@@ -444,7 +465,7 @@ export default class App extends Component {
 			${topbar}
 			<${ScrollManager} target=${this.buffer} scrollKey=${this.state.activeBuffer}>
 				<section id="buffer" ref=${this.buffer}>
-					<${Buffer} buffer=${activeBuffer}/>
+					<${Buffer} buffer=${activeBuffer} onNickClick=${this.handleNickClick}/>
 				</section>
 			</>
 			<${Composer} ref=${this.composer} readOnly=${this.state.activeBuffer == SERVER_BUFFER} onSubmit=${this.handleComposerSubmit}/>
diff --git a/components/buffer.js b/components/buffer.js
index 112ac0e..802622e 100644
--- a/components/buffer.js
+++ b/components/buffer.js
@@ -13,7 +13,7 @@ function djb2(s) {
 function Nick(props) {
 	function handleClick(event) {
 		event.preventDefault();
-		// TODO
+		props.onClick();
 	}
 
 	var colorIndex = djb2(props.nick) % 16 + 1;
@@ -25,6 +25,12 @@ function Nick(props) {
 function LogLine(props) {
 	var msg = props.message;
 
+	function createNick(nick) {
+		return html`
+			<${Nick} nick=${nick} onClick=${() => props.onNickClick(nick)}/>
+		`;
+	}
+
 	var date = new Date(msg.tags["time"]);
 	var timestamp = date.toLocaleTimeString(undefined, {
 		timeStyle: "short",
@@ -46,32 +52,32 @@ function LogLine(props) {
 			var action = text.slice(actionPrefix.length, -1);
 
 			lineClass = "me-tell";
-			content = html`* <${Nick} nick=${msg.prefix.name}/> ${linkify(action)}`;
+			content = html`* ${createNick(msg.prefix.name)} ${linkify(action)}`;
 		} else {
 			lineClass = "talk";
-			content = html`${"<"}<${Nick} nick=${msg.prefix.name}/>${">"} ${linkify(text)}`;
+			content = html`${"<"}${createNick(msg.prefix.name)}${">"} ${linkify(text)}`;
 		}
 		break;
 	case "JOIN":
 		content = html`
-			<${Nick} nick=${msg.prefix.name}/> has joined
+			${createNick(msg.prefix.name)} has joined
 		`;
 		break;
 	case "PART":
 		content = html`
-			<${Nick} nick=${msg.prefix.name}/> has left
+			${createNick(msg.prefix.name)} has left
 		`;
 		break;
 	case "NICK":
 		var newNick = msg.params[0];
 		content = html`
-			<${Nick} nick=${msg.prefix.name}/> is now known as <${Nick} nick=${newNick}/>
+			${createNick(msg.prefix.name)} is now known as <${Nick} nick=${newNick}/>
 		`;
 		break;
 	case "TOPIC":
 		var topic = msg.params[1];
 		content = html`
-			<${Nick} nick=${msg.prefix.name}/> changed the topic to: ${linkify(topic)}
+			${createNick(msg.prefix.name)} changed the topic to: ${linkify(topic)}
 		`;
 		break;
 	default:
@@ -91,7 +97,7 @@ export default function Buffer(props) {
 	return html`
 		<div class="logline-list">
 			${props.buffer.messages.map((msg) => html`
-				<${LogLine} message=${msg}/>
+				<${LogLine} message=${msg} onNickClick=${props.onNickClick}/>
 			`)}
 		</div>
 	`;