diff --git a/client/components/App.vue b/client/components/App.vue
index b788a86e..09841cde 100644
--- a/client/components/App.vue
+++ b/client/components/App.vue
@@ -15,7 +15,6 @@
import throttle from "lodash/throttle";
import constants from "../js/constants";
import storage from "../js/localStorage";
-import {generateUserContextMenu} from "../js/helpers/contextMenu";
import Sidebar from "./Sidebar.vue";
import ImageViewer from "./ImageViewer.vue";
@@ -89,27 +88,6 @@ export default {
this.$store.commit("userlistOpen", isUserlistOpen === "true");
},
- openContextMenu(event, items) {
- // TODO: maybe move this method to the store or some other more accessible place
- this.$refs.contextMenu.open(event, items);
- },
- openContextMenuForMentionedNick(event, network, nick) {
- // TODO: Find a better way to do this
-
- const channel = this.$store.state.activeChannel.channel;
- let user = channel.users.find((u) => u.nick === nick);
-
- if (!user) {
- user = {
- nick: nick,
- mode: "",
- };
- }
-
- const items = generateUserContextMenu(this.$root, channel, network, user);
-
- this.openContextMenu(event, items);
- },
},
};
diff --git a/client/components/ChannelWrapper.vue b/client/components/ChannelWrapper.vue
index c7d1ffd4..83a53201 100644
--- a/client/components/ChannelWrapper.vue
+++ b/client/components/ChannelWrapper.vue
@@ -25,7 +25,6 @@
diff --git a/client/components/ContextMenu.vue b/client/components/ContextMenu.vue
index ff2cd94c..fd07da25 100644
--- a/client/components/ContextMenu.vue
+++ b/client/components/ContextMenu.vue
@@ -35,6 +35,7 @@
diff --git a/client/components/ParsedMessage.vue b/client/components/ParsedMessage.vue
index 52538a9a..842cbb34 100644
--- a/client/components/ParsedMessage.vue
+++ b/client/components/ParsedMessage.vue
@@ -16,8 +16,7 @@ export default {
? context.props.text
: context.props.message.text,
context.props.message,
- context.props.network,
- context.parent.$root
+ context.props.network
);
},
};
diff --git a/client/components/Username.vue b/client/components/Username.vue
index 64444f21..8e3a255a 100644
--- a/client/components/Username.vue
+++ b/client/components/Username.vue
@@ -4,8 +4,8 @@
:data-name="user.nick"
role="button"
v-on="onHover ? {mouseover: hover} : {}"
- @click.prevent="rightClick($event)"
- @contextmenu.prevent="rightClick($event)"
+ @click.prevent="openContextMenu"
+ @contextmenu.prevent="openContextMenu"
>{{ user.mode }}{{ user.nick }}
@@ -19,7 +19,6 @@ export default {
user: Object,
active: Boolean,
onHover: Function,
- contextMenuCallback: Function,
},
computed: {
nickColor() {
@@ -30,10 +29,11 @@ export default {
hover() {
return this.onHover(this.user);
},
- rightClick($event) {
- if (this.contextMenuCallback) {
- this.contextMenuCallback($event, this.user);
- }
+ openContextMenu(event) {
+ this.$root.$emit("contextmenu:user", {
+ event: event,
+ user: this.user,
+ });
},
},
};
diff --git a/client/components/UsernameFiltered.vue b/client/components/UsernameFiltered.vue
index 62881a17..d8e68380 100644
--- a/client/components/UsernameFiltered.vue
+++ b/client/components/UsernameFiltered.vue
@@ -3,9 +3,9 @@
:class="['user', nickColor, {active: active}]"
:data-name="user.original.nick"
role="button"
- @mouseover="hover"
- @click.prevent="rightClick($event)"
- @contextmenu.prevent="rightClick($event)"
+ @mouseover="onHover(user.original)"
+ @click.prevent="openContextMenu"
+ @contextmenu.prevent="openContextMenu"
v-html="user.original.mode + user.string"
/>
@@ -19,7 +19,6 @@ export default {
user: Object,
active: Boolean,
onHover: Function,
- contextMenuCallback: Function,
},
computed: {
nickColor() {
@@ -27,13 +26,11 @@ export default {
},
},
methods: {
- hover() {
- this.onHover ? this.onHover(this.user.original) : null;
- },
- rightClick($event) {
- if (this.contextMenuCallback) {
- this.contextMenuCallback($event, this.user);
- }
+ openContextMenu(event) {
+ this.$root.$emit("contextmenu:user", {
+ event: event,
+ user: this.user.original,
+ });
},
},
};
diff --git a/client/css/style.css b/client/css/style.css
index 86233b5e..2d86edcc 100644
--- a/client/css/style.css
+++ b/client/css/style.css
@@ -2133,6 +2133,7 @@ part/quit messages where we don't load previews (adds a blank line otherwise) */
line-height: 1.4;
transition: background-color 0.2s;
border-radius: 3px;
+ white-space: nowrap;
}
.context-menu-item.active,
diff --git a/client/js/helpers/contextMenu.js b/client/js/helpers/contextMenu.js
index ef7cfd2a..334ab25e 100644
--- a/client/js/helpers/contextMenu.js
+++ b/client/js/helpers/contextMenu.js
@@ -91,52 +91,46 @@ export function generateChannelContextMenu($root, channel, network) {
// Add menu items for channels
if (channel.type === "channel") {
- items = [
- ...items,
- {
- label: "Edit topic",
- type: "item",
- class: "edit",
- action() {
- channel.editTopic = true;
- $root.switchToChannel(channel);
+ items.push({
+ label: "Edit topic",
+ type: "item",
+ class: "edit",
+ action() {
+ channel.editTopic = true;
+ $root.switchToChannel(channel);
- $root.$nextTick(() =>
- document.querySelector(`#chan-${channel.id} .topic-input`).focus()
- );
- },
+ $root.$nextTick(() =>
+ document.querySelector(`#chan-${channel.id} .topic-input`).focus()
+ );
},
- {
- label: "List banned users",
- type: "item",
- class: "list",
- action() {
- socket.emit("input", {
- target: channel.id,
- text: "/banlist",
- });
- },
+ });
+ items.push({
+ label: "List banned users",
+ type: "item",
+ class: "list",
+ action() {
+ socket.emit("input", {
+ target: channel.id,
+ text: "/banlist",
+ });
},
- ];
+ });
}
// Add menu items for queries
if (channel.type === "query") {
- items = [
- ...items,
- {
- label: "User information",
- type: "item",
- class: "action-whois",
- action() {
- $root.switchToChannel(channel);
- socket.emit("input", {
- target: $root.$store.state.activeChannel.channel.id,
- text: "/whois " + channel.name,
- });
- },
+ items.push({
+ label: "User information",
+ type: "item",
+ class: "action-whois",
+ action() {
+ $root.switchToChannel(channel);
+ socket.emit("input", {
+ target: channel.id,
+ text: "/whois " + channel.name,
+ });
},
- ];
+ });
}
// Add close menu item
@@ -159,7 +153,7 @@ export function generateChannelContextMenu($root, channel, network) {
}
export function generateUserContextMenu($root, channel, network, user) {
- const currentChannelUser = channel.users.filter((u) => u.nick === network.nick)[0];
+ const currentChannelUser = channel.users.find((u) => u.nick === network.nick) || {};
const whois = () => {
const chan = $root.$store.getters.findChannelOnCurrentNetwork(user.nick);
diff --git a/client/js/helpers/parse.js b/client/js/helpers/parse.js
index f50f0181..61a388a1 100644
--- a/client/js/helpers/parse.js
+++ b/client/js/helpers/parse.js
@@ -6,11 +6,11 @@ import findLinks from "./ircmessageparser/findLinks";
import findEmoji from "./ircmessageparser/findEmoji";
import findNames from "./ircmessageparser/findNames";
import merge from "./ircmessageparser/merge";
-import colorClass from "./colorClass";
import emojiMap from "./fullnamemap.json";
import LinkPreviewToggle from "../../components/LinkPreviewToggle.vue";
import LinkPreviewFileSize from "../../components/LinkPreviewFileSize.vue";
import InlineChannel from "../../components/InlineChannel.vue";
+import Username from "../../components/Username.vue";
const emojiModifiersRegex = /[\u{1f3fb}-\u{1f3ff}]/gu;
@@ -70,7 +70,7 @@ function createFragment(fragment, createElement) {
// Transform an IRC message potentially filled with styling control codes, URLs,
// nicknames, and channels into a string of HTML elements to display on the client.
-function parse(createElement, text, message = undefined, network = undefined, $root) {
+function parse(createElement, text, message = undefined, network = undefined) {
// Extract the styling information and get the plain text version from it
const styleFragments = parseStyle(text);
const cleanText = styleFragments.map((fragment) => fragment.text).join("");
@@ -180,23 +180,16 @@ function parse(createElement, text, message = undefined, network = undefined, $r
fragments
);
} else if (textPart.nick) {
- // TODO: This really does not belong here, find a better way
- const openContextMenu = (event) => {
- $root.$refs.app.openContextMenuForMentionedNick(event, network, textPart.nick);
- };
-
return createElement(
- "span",
+ Username,
{
- class: ["user", colorClass(textPart.nick)],
- attrs: {
- role: "button",
- dir: "auto",
- "data-name": textPart.nick,
+ props: {
+ user: {
+ nick: textPart.nick,
+ },
},
- on: {
- contextmenu: openContextMenu,
- click: openContextMenu,
+ attrs: {
+ dir: "auto",
},
},
fragments
diff --git a/test/client/js/helpers/parse.js b/test/client/js/helpers/parse.js
index 6fe009b7..9cdce2b8 100644
--- a/test/client/js/helpers/parse.js
+++ b/test/client/js/helpers/parse.js
@@ -358,7 +358,7 @@ describe("IRC formatted message parser", () => {
input: "test, MaxLeiter",
expected:
"test, " +
- '' +
+ '' +
"MaxLeiter" +
"",
},