Skip to content

Commit

Permalink
feat: emit an event for all link open requests
Browse files Browse the repository at this point in the history
  • Loading branch information
valeriansaliou committed Mar 9, 2024
1 parent 631899c commit de7a519
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 3 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ The following namespaces are available for use:
- `message:reactions:view`: show the list of reactions that can be sent for message
- `message:reactions:react`: react to a message (eg. user clicks on an existing reaction to send it or retract it)
- `message:file:view`: view a file from a message (eg. user clicks on a file to expand or download the file)
- `message:link:open`: open a link contained in a message (eg. user clicks on a link)
- `message:history:view`: notify when a message from history enters or leaves view area, with the `visible` and `hidden` states (eg. scrolling up or down in the timeline)
- `message:history:seek`: request to load `backwards` or `forwards` history (eg. scrolling back in time to load past messages)

Expand Down
68 changes: 67 additions & 1 deletion src/messaging/components/message/message.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

// IMPORTS

import { nextTick } from "petite-vue";
import { htmlEscape as _e } from "escape-goat";
import linkifyHtml from "linkify-html";
import snarkdown from "snarkdown";
Expand Down Expand Up @@ -241,6 +242,10 @@ function MessagePartText(content) {
mounted() {
// Generate text message HTML
this.html = this.__generateHTML(content);

// Bind link click events
// Notice: ensure DOM has been rendered w/ HTML content
nextTick(this.__bindLinkClickEvents);
},

/**
Expand All @@ -260,11 +265,72 @@ function MessagePartText(content) {
htmlContent = linkifyHtml(htmlContent, TEXT_LINKIFY_OPTIONS);

return htmlContent;
},

/**
* Binds link click events
* @private
* @return {undefined}
*/
__bindLinkClickEvents() {
// Bind click event on all links? (if any text element)
// Notice: since we are generating custom HTML code outside of Vue, then \
// we cannot use the standard '@click' event and have to resort to \
// using the non-Vue 'addEventListener()'.
if (this.$refs.textInner) {
const linkElements =
this.$refs.textInner.getElementsByTagName("a") || [];

if (linkElements.length > 0) {
for (const linkElement of linkElements) {
linkElement.addEventListener("click", this.__onLinkClick);
}
}
}
},

// --> EVENT LISTENERS <--

/**
* Triggers when a link is clicked
* @private
* @param {object} event
* @return {undefined}
*/
__onLinkClick(event) {
// Do not open link (let the implementing app choose what to do)
event.preventDefault();

// Handle link? (if any)
const linkUrl = event.target?.href || null;

if (linkUrl !== null) {
// Extract protocol from link (if any)
const protocolSeparatorIndex = linkUrl.indexOf(":");

let linkProtocol = null;

if (protocolSeparatorIndex > 0) {
linkProtocol = linkUrl
.substring(0, protocolSeparatorIndex)
.toLowerCase();
}

// Emit message link open event
$event._emit("message:link:open", {
id: content.id,

link: {
url: linkUrl,
protocol: linkProtocol
}
});
}
}
};
}

function MessagePartFile(content, file) {
function MessagePartFile(file) {
return {
// --> TEMPLATE <--

Expand Down
9 changes: 7 additions & 2 deletions src/messaging/messaging.html
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@
<span
v-for="file in line.files"
:key="'file/' + file.url"
v-scope="MessagePartFile(line, file)"
v-scope="MessagePartFile(file)"
@vue:mounted="mounted"
class="message-file"
></span>
Expand Down Expand Up @@ -220,7 +220,12 @@
<!-- TEMPLATES -->

<template id="template-message-part-text">
<span v-if="html" v-html="html" class="message-text-inner"></span>
<span
v-if="html"
v-html="html"
class="message-text-inner"
ref="textInner"
></span>

<span v-if="edited" class="message-text-flag">
({{ $context.i18n._.attributes.edited }})
Expand Down
1 change: 1 addition & 0 deletions src/messaging/stores/broker.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ function BrokerStore() {
"message:reactions:view",
"message:reactions:react",
"message:file:view",
"message:link:open",
"message:history:view",
"message:history:seek"
]),
Expand Down
9 changes: 9 additions & 0 deletions types/messaging.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,15 @@ export declare interface EventMessageFileView {
};
}

export declare interface EventMessageLinkOpen {
id: string;

link: {
url: string;
protocol: null | string;
};
}

export declare interface EventMessageHistoryView {
id: string;
visibility: ViewVisibility;
Expand Down

0 comments on commit de7a519

Please sign in to comment.