import { h, Component } from '/js/web_modules/preact.js'; import htm from '/js/web_modules/htm.js'; const html = htm.bind(h); import { messageBubbleColorForString } from '../../utils/user-colors.js'; import { convertToText } from '../../utils/chat.js'; import { SOCKET_MESSAGE_TYPES } from '../../utils/websocket.js'; export default class Message extends Component { render(props) { const { message, username } = props; const { type } = message; if (type === SOCKET_MESSAGE_TYPES.CHAT) { const { author, body, timestamp } = message; const formattedMessage = formatMessageText(body, username); const formattedTimestamp = formatTimestamp(timestamp); const authorColor = messageBubbleColorForString(author); const authorTextColor = { color: authorColor }; return ( html`
`); } else if (type === SOCKET_MESSAGE_TYPES.NAME_CHANGE) { const { oldName, newName } = message; return ( html` ` ); } } } export function formatMessageText(message, username) { let formattedText = highlightUsername(message, username); formattedText = getMessageWithEmbeds(formattedText); return convertToMarkup(formattedText); } function highlightUsername(message, username) { const pattern = new RegExp( '@?' + username.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'gi' ); return message.replace( pattern, '$&' ); } function getMessageWithEmbeds(message) { var embedText = ''; // Make a temporary element so we can actually parse the html and pull anchor tags from it. // This is a better approach than regex. var container = document.createElement('p'); container.innerHTML = message; var anchors = container.getElementsByTagName('a'); for (var i = 0; i < anchors.length; i++) { const url = anchors[i].href; if (getYoutubeIdFromURL(url)) { const youtubeID = getYoutubeIdFromURL(url); embedText += getYoutubeEmbedFromID(youtubeID); } else if (url.indexOf('instagram.com/p/') > -1) { embedText += getInstagramEmbedFromURL(url); } else if (isImage(url)) { embedText += getImageForURL(url); } } // If this message only consists of a single embeddable link // then only return the embed and strip the link url from the text. if (embedText !== '' && anchors.length == 1 && isMessageJustAnchor(message, anchors[0])) { return embedText; } return message + embedText; } function getYoutubeIdFromURL(url) { try { var regExp = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/; var match = url.match(regExp); if (match && match[2].length == 11) { return match[2]; } else { return null; } } catch (e) { console.log(e); return null; } } function getYoutubeEmbedFromID(id) { return ` `; } function getInstagramEmbedFromURL(url) { const urlObject = new URL(url.replace(/\/$/, '')); urlObject.pathname += '/embed'; return ``; } function isImage(url) { const re = /\.(jpe?g|png|gif)$/i; return re.test(url); } function getImageForURL(url) { return `