From 183e14e12fd90d1373e87387d562bacf975b64a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nikola=20Forr=C3=B3?= Date: Mon, 3 Aug 2020 15:46:35 +0200 Subject: [PATCH 1/3] Explicitly disable github @mentions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also remove doubled strikethrough option. Signed-off-by: Nikola Forró --- webroot/js/message.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webroot/js/message.js b/webroot/js/message.js index cd1c81460..bfcf3c718 100644 --- a/webroot/js/message.js +++ b/webroot/js/message.js @@ -23,10 +23,10 @@ class Message { emoji: true, openLinksInNewWindow: true, tables: false, - strikethrough: false, simplifiedAutoLink: false, literalMidWordUnderscores: true, strikethrough: true, + ghMentions: false, }).makeHtml(this.body); const linked = autoLink(markdownToHTML, { embed: true, From a0c609ce76d3fdc5e793f982102cf6fc5621353e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nikola=20Forr=C3=B3?= Date: Mon, 3 Aug 2020 15:49:42 +0200 Subject: [PATCH 2/3] Add username tab completion on @ character MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nikola Forró --- webroot/js/message.js | 68 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/webroot/js/message.js b/webroot/js/message.js index bfcf3c718..91406c7ef 100644 --- a/webroot/js/message.js +++ b/webroot/js/message.js @@ -51,6 +51,7 @@ class MessagingInterface { this.messageCharCount = 0; this.maxMessageLength = 500; this.maxMessageBuffer = 20; + this.chatUsernames = []; this.onReceivedMessages = this.onReceivedMessages.bind(this); this.disableChat = this.disableChat.bind(this); @@ -195,6 +196,42 @@ class MessagingInterface { this.send(nameChange); } + tryToComplete() { + const rawValue = this.formMessageInput.value; + const position = this.formMessageInput.selectionStart; + const at = rawValue.lastIndexOf('@', position - 1); + + if (at === -1) { + return false; + } + + var partial = rawValue.substring(at + 1, position).trim(); + + if (partial === this.suggestion) { + partial = this.partial; + } else { + this.partial = partial; + } + + const possibilities = this.chatUsernames.filter(function (username) { + return username.toLowerCase().startsWith(partial.toLowerCase()); + }); + + if (this.completionIndex === undefined || ++this.completionIndex >= possibilities.length) { + this.completionIndex = 0; + } + + if (possibilities.length > 0) { + this.suggestion = possibilities[this.completionIndex]; + + this.formMessageInput.value = rawValue.substring(0, at + 1) + this.suggestion + ' ' + rawValue.substring(position); + this.formMessageInput.selectionStart = at + this.suggestion.length + 2; + this.formMessageInput.selectionEnd = this.formMessageInput.selectionStart; + } + + return true; + } + handleMessageInputKeydown(event) { var okCodes = [37,38,39,40,16,91,18,46,8]; var value = this.formMessageInput.value.trim(); @@ -211,6 +248,15 @@ class MessagingInterface { if (event.keyCode === 16 || event.keyCode === 17) { // ctrl, shift this.prepNewLine = true; } + if (event.keyCode === 9) { // tab + if (this.tryToComplete()) { + event.preventDefault(); + + // value could have been changed, update variables + value = this.formMessageInput.value.trim(); + numCharsLeft = this.maxMessageLength - value.length; + } + } if (numCharsLeft <= this.maxMessageBuffer) { this.tagMessageFormWarning.innerText = `${numCharsLeft} chars left`; @@ -287,6 +333,28 @@ class MessagingInterface { // handle Vue.js message display onReceivedMessages(newMessages, oldMessages) { + // update the list of chat usernames + newMessages.slice(oldMessages.length).forEach(function (message) { + var username; + + switch (message.type) { + case SOCKET_MESSAGE_TYPES.CHAT: + username = message.author; + break; + + case SOCKET_MESSAGE_TYPES.NAME_CHANGE: + username = message.newName; + break; + + default: + return; + } + + if (!this.chatUsernames.includes(username)) { + this.chatUsernames.push(username); + } + }, this); + if (newMessages.length !== oldMessages.length) { // jump to bottom jumpToBottom(this.scrollableMessagesContainer); From b6ad96da2806a4b6da5b284500c820044a870275 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nikola=20Forr=C3=B3?= Date: Tue, 4 Aug 2020 16:17:26 +0200 Subject: [PATCH 3/3] Highlight self-mentions in messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nikola Forró --- webroot/js/message.js | 9 ++++++++- webroot/styles/layout.css | 5 +++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/webroot/js/message.js b/webroot/js/message.js index 91406c7ef..e000c992c 100644 --- a/webroot/js/message.js +++ b/webroot/js/message.js @@ -35,11 +35,18 @@ class Message { target: '_blank' } }); - return addNewlines(linked); + const highlighted = this.highlightUsername(linked); + return addNewlines(highlighted); } userColor() { return messageBubbleColorForString(this.author); } + + highlightUsername(message) { + const username = document.getElementById('self-message-author').value; + const pattern = new RegExp('@?' + username.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'gi'); + return message.replace(pattern, '$&'); + } } diff --git a/webroot/styles/layout.css b/webroot/styles/layout.css index 0339d38de..81de24302 100644 --- a/webroot/styles/layout.css +++ b/webroot/styles/layout.css @@ -624,6 +624,11 @@ h2 { border-radius: 15px; } +.message-text .highlighted { + color: orange; + font-weight: bold; +} + .message-text code { background-color:darkslategrey; padding: 3px;