service-matrix/matrix/format.ts
2023-08-07 16:55:11 +03:00

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(' ');
}
}