I’m working on a chat application where users can message each other. I have used the anchorme library to detect links / URLs / Emails in text and convert them to clickable HTML which it does. But the detected URLs are not clickable it is just converted as plain
text. Is there a way to convert it to a hyperlink?
<!DOCTYPE html> <html> <head> <link rel="stylesheet" href="css/styles.min.css"> </head> <body> <div class="chat"> <div id="sidebar" class="chat__sidebar"> </div> <div class="chat__main"> <div id="messages" class="chat__messages"></div> <div class="compose"> <form id="message-form"> <input name="msg" placeholder="Message" required autocomplete="off"> <button>Send message</button> </form> <button id="send-location">Send location</button> </div> </div> </div> <script id="message-template" type="text/html"> <div class="message"> <p> <span class="message__name">{{username}}</span> <span class="message__meta">{{createdAt}}</span> </p> <p>{{message}}</p> </div> </script> <script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/3.0.1/mustache.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/qs/6.6.0/qs.min.js"></script> <script src="/socket.io/socket.io.js"></script> <script src="/js/chat.js"></script> <script src="https://raw.githack.com/alexcorvi/anchorme.js/gh-pages/dist/browser/anchorme.min.js"></script> </body> </html>
Javascript client side:
> const socket = io()
>
> //Elements
> const msg = document.querySelector('#message-form')
> const messageFormInput = msg.querySelector('input')
> const messageFormButton = msg.querySelector('button')
>
> //Templates
> const messages = document.querySelector("#messages")
> const messageTemplate = document.querySelector('#message-template').innerHTML
>
>
>
> //ref to index.js
> socket.on('message', (message) => {
> const html = Mustache.render(messageTemplate, {
> //will come from the value
> username: message.username,
> message: message.text,
> createdAt: moment(message.createdAt).format('HH:mm')
> })
> messages.insertAdjacentHTML('beforeend', html)
> scrollAuto()
> })
>
> //Refers to html form input
> msg.addEventListener('submit', (e) => {
> //Prevents browser to update
> e.preventDefault()
>
> messageFormButton.setAttribute('disabled', 'disabled')
>
> const message = e.target.elements.msg.value
> socket.emit('sendMsg', message, (error) => {
> messageFormButton.removeAttribute('disabled')
> messageFormInput.value = ''
> messageFormInput.focus()
> //Enable after event acknowledged
>
> if (error) {
> return console.log(error)
> }
> })
> })
>
> socket.emit('join', {
> username,
> room
> }, (error) => {
> if (error) {
> alert(error)
> location.href = '/'
> }
>
> })
>
Javascript server:
> const path = require('path')
> const http = require('http')
> const express = require('express')
> const socketio = require('socket.io')
>
> //Destructuring
> const {
> generateMessage,
> } = require('./utils/messages')
>
> // Convert Urls
> const anchorme = require("anchorme").default;
> // Check for profanity
> const Filter = require('bad-words')
> //Initiate socket-io
> const io = socketio(server)
>
> // Define path for Express config
> const publicDirectoryPath = path.join(__dirname, '../public')
> app.use(express.static(publicDirectoryPath))
>
> //Server-side
> io.on('connection', (socket) => {
> console.log(' WebSocket Connection')
>
> // Listening for socket i.e messages
> socket.on('sendMsg', (message, callback) => {
> const user = getUser(socket.id)
>
> var result = anchorme(message, {
> attributes: [{
> name: "target",
> value: "_blank"
> }, ]
> });
> console.log(result)
>
> var filter = new Filter()
> if (filter.isProfane(message)) {
> return callback('Profanity is not allowed')
> }
> io.to(user.room).emit('message', generateMessage(user.username, result))
> callback()
> })
> })
>
const generateMessage = (username, text) => {
> return {
> username,
> text,
> createdAt: new Date().getTime()
> } }