134 lines
3.5 KiB
TypeScript
134 lines
3.5 KiB
TypeScript
import { thousandsSeparator, toHHMMSS, timeSince } from '@squeebot/core/lib/common';
|
|
import { HTMLFormatter } from '@squeebot/core/lib/types';
|
|
|
|
export class MatrixFormatter extends HTMLFormatter {
|
|
colors: { [key: string]: string } = {
|
|
black: '#000000',
|
|
darkblue: '#00007f',
|
|
green: '#009300',
|
|
red: '#ff0000',
|
|
brown: '#7f0000',
|
|
purple: '#9c009c',
|
|
gold: '#fc7f00',
|
|
yellow: '#ffff00',
|
|
limegreen: '#00fc00',
|
|
cyan: '#00ffff',
|
|
lightblue: '#0000fc',
|
|
blue: '#009393',
|
|
pink: '#ff00ff',
|
|
darkgray: '#7f7f7f',
|
|
gray: '#d2d2d2',
|
|
white: '#ffffff'
|
|
};
|
|
|
|
public override color(color: string, msg: string): string {
|
|
return `<span data-mx-color="${this.colors[color] || '#000000'}">${msg}</span>`;
|
|
}
|
|
|
|
public override format(method: string, msg: string): string {
|
|
if (method === 'action') return `<m.emote>${msg}</m.emote>`;
|
|
return super.format(method, msg);
|
|
}
|
|
|
|
override compose(objs: any): any {
|
|
const str = [];
|
|
|
|
for (const i in objs) {
|
|
const elem = objs[i];
|
|
|
|
const elemType = elem[0];
|
|
let elemValue = elem[1];
|
|
const elemParams = elem[2];
|
|
|
|
if (!elemValue) {
|
|
continue;
|
|
}
|
|
|
|
let valueColor = null;
|
|
|
|
// Special types
|
|
if (elemParams && elemParams.type) {
|
|
switch (elemParams.type) {
|
|
case 'time':
|
|
elemValue = new Date(elemValue).toString();
|
|
break;
|
|
case 'metric':
|
|
elemValue = thousandsSeparator(elemValue);
|
|
break;
|
|
case 'timesince':
|
|
elemValue = timeSince(elemValue);
|
|
break;
|
|
case 'duration':
|
|
elemValue = toHHMMSS(elemValue);
|
|
break;
|
|
case 'description':
|
|
valueColor = 'blue';
|
|
elemValue = `"${elemValue}"`;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Currently, disregard image fields.
|
|
if (elemType === 'image') {
|
|
continue;
|
|
}
|
|
|
|
// Bold value
|
|
if (elemType === 'bold' || elemType === 'b' || elemType === 'strong') {
|
|
elemValue = this.format('bold', elemValue);
|
|
}
|
|
|
|
// Italic value
|
|
if (elemType === 'italic' || elemType === 'i' || elemType === 'em' || elemType === 'emphasis') {
|
|
elemValue = this.format('italic', elemValue);
|
|
}
|
|
|
|
// Underlined value
|
|
if (elemType === 'underline' || elemType === 'ul') {
|
|
elemValue = this.format('underline', elemValue);
|
|
}
|
|
|
|
// Colorize the value
|
|
if (elemParams?.color) {
|
|
valueColor = elemParams.color;
|
|
}
|
|
|
|
// Add the label, if present
|
|
if (elemParams?.label) {
|
|
// Set label color to default
|
|
let labelColor = 'green';
|
|
if (elemParams.color) {
|
|
labelColor = elemParams.color;
|
|
}
|
|
|
|
if (!valueColor) {
|
|
valueColor = 'blue';
|
|
}
|
|
|
|
// Handle array label
|
|
// Prefer the label over the icon version.
|
|
let label = elemParams.label;
|
|
if (typeof label === 'object') {
|
|
label = elemParams.label[elemParams.label.length - 1];
|
|
} else {
|
|
label = label;
|
|
}
|
|
|
|
// Add colon
|
|
label = `${label}:`;
|
|
|
|
if (valueColor && valueColor === labelColor) {
|
|
str.push(this.color(valueColor, label + ' ' + elemValue));
|
|
} else {
|
|
str.push(this.color(labelColor, label) + ' ' + (valueColor ? this.color(valueColor, elemValue) : elemValue));
|
|
}
|
|
} else {
|
|
str.push(valueColor ? this.color(valueColor, elemValue) : elemValue);
|
|
}
|
|
}
|
|
|
|
// May return an object, but your protocol must support it.
|
|
return str.join(' ');
|
|
}
|
|
}
|