Skip to content

Commit

Permalink
Message formatting.
Browse files Browse the repository at this point in the history
  • Loading branch information
Armored-Dragon committed Nov 30, 2024
1 parent 7779129 commit 54b4aa7
Show file tree
Hide file tree
Showing 2 changed files with 174 additions and 69 deletions.
86 changes: 81 additions & 5 deletions scripts/system/domainChat/domainChat.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html

// TODO: Message trimming

(() => {
("use strict");

Expand Down Expand Up @@ -110,8 +112,12 @@
// Format the timestamp
message.timeString = timeArray[0];
message.dateString = timeArray[1];

_emitEvent({ type: "show_message", ...message }); // Update qml view of to new message.

let formattedMessage = _parseMessage(message.message); // Format the message for viewing
let formattedMessagePacket = { ...message };
formattedMessagePacket.message = formattedMessage

_emitEvent({ type: "show_message", ...formattedMessagePacket }); // Update qml view of to new message.
_notificationCoreMessage(message.displayName, message.message) // Show a new message on screen.

// Create a new variable based on the message that will be saved.
Expand Down Expand Up @@ -238,9 +244,15 @@
// Load message history
messageHistory.forEach((message) => {
const timeArray = _formatTimestamp(_getTimestamp());
message.timeString = timeArray[0];
message.dateString = timeArray[1];
_emitEvent({ type: "show_message", ...message });
messagePacket = { ...message };
messagePacket.timeString = timeArray[0];
messagePacket.dateString = timeArray[1];

let formattedMessage = _parseMessage(messagePacket.message);
let formattedMessagePacket = messagePacket;
formattedMessagePacket.message = formattedMessage;

_emitEvent({ type: "show_message", ...formattedMessagePacket });
});
}

Expand Down Expand Up @@ -275,6 +287,70 @@
JSON.stringify({ sender: displayName, text: message })
);
}
function _parseMessage(message){
const urlRegex = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/;
const mentionRegex = /@(\w+)/; // FIXME: Remove - devcode
const overteLocationRegex = null;

let runningMessage = message;
let messageArray = [];

const regexPatterns = [
{ type: "url", regex: urlRegex },
{ type: "mention", regex: mentionRegex }, // FIXME: Remove - devcode
{ type: "overteLocation", regex: overteLocationRegex }
]

// Here is a link https://www.example.com, #hashtag, and @mention. Just for some spice here is another https://exampletwo.com

while (true) {
let firstMatch = _findFirstMatch();

if (firstMatch == null) {
// If there was not any matches found in the entire message, format the whole message as a single text entry.
messageArray.push({type: 'text', value: runningMessage});

// Append a final 'fill width' to the message text.
messageArray.push({type: 'messageEnd'});
break;
}

_formatMessage(firstMatch);
}

return messageArray;

function _formatMessage(firstMatch){
let indexOfFirstMatch = firstMatch[0];
let regex = regexPatterns[firstMatch[1]].regex;

let foundMatch = runningMessage.match(regex)[0];

messageArray.push({type: 'text', value: runningMessage.substring(0, indexOfFirstMatch)});
messageArray.push({type: regexPatterns[firstMatch[1]].type, value: runningMessage.substring(indexOfFirstMatch, indexOfFirstMatch + foundMatch.length)});

runningMessage = runningMessage.substring(indexOfFirstMatch + foundMatch.length); // Remove the part of the message we have worked with
}

function _findFirstMatch(){
let indexOfFirstMatch = Infinity;
let indexOfRegexPattern = Infinity;

for (let i = 0; regexPatterns.length > i; i++){
let indexOfMatch = runningMessage.search(regexPatterns[i].regex);

if (indexOfMatch == -1) continue; // No match found

if (indexOfMatch < indexOfFirstMatch) {
indexOfFirstMatch = indexOfMatch;
indexOfRegexPattern = i;
}
}

if (indexOfFirstMatch !== Infinity) return [indexOfFirstMatch, indexOfRegexPattern]; // If there was a found match
return null; // No found match
}
}

/**
* Emit a packet to the HTML front end. Easy communication!
Expand Down
157 changes: 93 additions & 64 deletions scripts/system/domainChat/domainChat.qml
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ Rectangle {
model: getChannel(pageVal)
delegate: Loader {
property int delegateIndex: model.index
property string delegateText: model.text
property var delegateText: model.text
property string delegateUsername: model.username
property string delegateDate: model.date

Expand Down Expand Up @@ -384,7 +384,7 @@ Rectangle {

Rectangle {
property int index: delegateIndex
property string texttest: delegateText
property var texttest: delegateText
property string username: delegateUsername
property string date: delegateDate

Expand All @@ -410,22 +410,83 @@ Rectangle {
}
}

TextEdit {
anchors.top: parent.children[0].bottom
x: 5
text: texttest
color:"white"
font.pointSize: 12
readOnly: true
selectByMouse: true
selectByKeyboard: true
Flow {
anchors.top: parent.children[0].bottom;
width: parent.width * 0.8
height: contentHeight
wrapMode: Text.Wrap
textFormat: TextEdit.RichText
x: 5

Repeater {
model: texttest;

RowLayout {
width: {
switch (model.type) {
case "text":
return children[0].width;
case "url":
return children[1].width;
}
}

Text {
text: model.value || ""
font.pointSize: 12
wrapMode: Text.Wrap
width: Math.min(parent.parent.parent.width, contentWidth);

visible: model.type === 'text' || model.type === 'mention';

color: {
switch (model.type) {
case "mention":
return "purple";
default:
return "white";
}
}
}

RowLayout {
width: Math.min(parent.parent.parent.width, children[0].contentWidth);
visible: model.type === 'url';

Text {
text: model.value || ""
font.pointSize: 12
wrapMode: Text.Wrap
color: "#4EBAFD";
font.underline: true

MouseArea {
anchors.fill: parent;

onClicked: {
Window.openWebBrowser(model.value)
}
}
}

onLinkActivated: {
Window.openWebBrowser(link)
Text {
text: "🗗"
font.pointSize: 10
wrapMode: Text.Wrap
color: "white"

MouseArea {
anchors.fill: parent;

onClicked: {
Qt.openUrlExternally(model.value)
}
}
}
}

Item {
Layout.fillWidth: true
visible: model.type === 'messageEnd'
}
}
}
}
}
Expand All @@ -436,7 +497,7 @@ Rectangle {

Rectangle{
property int index: delegateIndex
property string texttest: delegateText
property var texttest: delegateText
property string username: delegateUsername
property string date: delegateDate
color: "#171717"
Expand Down Expand Up @@ -517,8 +578,6 @@ Rectangle {
channel = getChannel(channel)

// Format content
message = formatContent(message);
message = embedImages(message);

if (type === "notification"){
channel.append({ text: message, date: date, type: "notification" });
Expand All @@ -529,23 +588,24 @@ Rectangle {
return;
}

var current_time = new Date();
var elapsed_time = current_time - last_message_time;
var elapsed_minutes = elapsed_time / (1000 * 60);
// TODO: Replace new time generation with time pregenerated from message
// var current_time = new Date();
// var elapsed_time = current_time - last_message_time;
// var elapsed_minutes = elapsed_time / (1000 * 60);

var last_item_index = channel.count - 1;
var last_item = channel.get(last_item_index);
// var last_item_index = channel.count - 1;
// var last_item = channel.get(last_item_index);

if (last_message_user === username && elapsed_minutes < 1 && last_item){
message = "<br>" + message
last_item.text = last_item.text += "\n" + message;
load_scroll_timer.running = true;
last_message_time = new Date();
return;
}
// if (last_message_user === username && elapsed_minutes < 1 && last_item){
// message = "<br>" + message
// last_item.text = last_item.text += "\n" + message;
// load_scroll_timer.running = true;
// last_message_time = new Date();
// return;
// }

last_message_user = username;
last_message_time = new Date();
// last_message_user = username;
// last_message_time = new Date();
channel.append({ text: message, username: username, date: date, type: type });
load_scroll_timer.running = true;
}
Expand All @@ -554,37 +614,6 @@ Rectangle {
return channels[id];
}

function formatContent(mess) {
var arrow = /\</gi
mess = mess.replace(arrow, "&lt;");

var link = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/g;
mess = mess.replace(link, (match) => {return `<a style="color:#4EBAFD" onclick='Window.openUrl("+match+")' href='` + match + `'>` + match + `</a> <a onclick='Window.openUrl(`+match+`)'>🗗</a>`});

var newline = /\n/gi;
mess = mess.replace(newline, "<br>");
return mess
}

function embedImages(mess){
var image_link = /(https?:(\/){2})[\w.-]+(?:\.[\w\.-]+)+(?:\/[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]*)(?:png|jpe?g|gif|bmp|svg|webp)/g;
var matches = mess.match(image_link);
var new_message = ""
var listed = []
var total_emeds = 0

new_message += mess

for (var i = 0; matches && matches.length > i && total_emeds < 3; i++){
if (!listed.includes(matches[i])) {
new_message += "<br><img src="+ matches[i] +" width='250' >"
listed.push(matches[i]);
total_emeds++
}
}
return new_message;
}

// Messages from script
function fromScript(message) {

Expand Down

0 comments on commit 54b4aa7

Please sign in to comment.