about summary refs log tree commit diff
path: root/LibMatrix/Helpers/MessageBuilder.cs
blob: d8970780a0fd159775f829d47d20b227981d3f6f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
using LibMatrix.EventTypes.Spec;

namespace LibMatrix.Helpers;

public class MessageBuilder(string msgType = "m.text", string format = "org.matrix.custom.html") {
    private RoomMessageEventContent Content { get; set; } = new() {
        MessageType = msgType,
        Format = format
    };

    public RoomMessageEventContent Build() => Content;

    public MessageBuilder WithBody(string body) {
        Content.Body += body;
        Content.FormattedBody += body;
        return this;
    }

    public MessageBuilder WithHtmlTag(string tag, string body, Dictionary<string, string>? attributes = null) {
        Content.Body += body;
        Content.FormattedBody += $"<{tag}";
        if (attributes != null)
            foreach (var (key, value) in attributes)
                Content.FormattedBody += $" {key}=\"{value}\"";
        Content.FormattedBody += $">{body}</{tag}>";
        return this;
    }

    public MessageBuilder WithHtmlTag(string tag, Action<MessageBuilder> bodyBuilder, Dictionary<string, string>? attributes = null) {
        Content.FormattedBody += $"<{tag}";
        if (attributes != null)
            foreach (var (key, value) in attributes)
                Content.FormattedBody += $" {key}=\"{value}\"";
        Content.FormattedBody += ">";
        bodyBuilder(this);
        Content.FormattedBody += $"</{tag}>";
        return this;
    }

    public MessageBuilder WithColoredBody(string color, string body) {
        Content.Body += body;
        Content.FormattedBody += $"<font color=\"{color}\">{body}</font>";
        return this;
    }

    public MessageBuilder WithColoredBody(string color, Action<MessageBuilder> bodyBuilder) {
        Content.FormattedBody += $"<font color=\"{color}\">";
        bodyBuilder(this);
        Content.FormattedBody += "</font>";
        return this;
    }

    public MessageBuilder WithCustomEmoji(string mxcUri, string name) {
        Content.Body += $"{{{name}}}";
        Content.FormattedBody += $"<img data-mx-emoticon height=\"32\" src=\"{mxcUri}\" alt=\"{name}\" title=\"{name}\" />";
        return this;
    }

    public MessageBuilder WithRainbowString(string text, byte skip = 1, int offset = 0, double lengthFactor = 255.0, bool useLength = true) {
        if (useLength) {
            lengthFactor = text.Length;
        }

        // HslaColorInterpolator interpolator = new((0, 255, 128, 255), (255, 255, 128, 255));
        // // RainbowEnumerator enumerator = new(skip, offset, lengthFactor);
        // for (int i = 0; i < text.Length; i++) {
        //     // var (r, g, b) = enumerator.Next();
        //     // var (r,g,b,a) = interpolator.Interpolate((i+offset) * skip, lengthFactor).ToRgba();
        //     // Console.WriteLine($"RBA: {r} {g} {b} {a}");
        //     // Content.FormattedBody += $"<font color=\"#{r:X2}{g:X2}{b:X2}\">{text[i]}</font>";
        // }
        return this;
    }

    public MessageBuilder WithCodeBlock(string code, string language = "plaintext") {
        Content.Body += code;
        Content.FormattedBody += $"<pre><code class=\"language-{language}\">{code}</code></pre>";
        return this;
    }

    public MessageBuilder WithCollapsibleSection(string title, string body) {
        Content.Body += body;
        Content.FormattedBody += $"<details><summary>{title}</summary>{body}</details>";
        return this;
    }

    public MessageBuilder WithCollapsibleSection(string title, Action<MessageBuilder> bodyBuilder) {
        Content.FormattedBody += $"<details><summary>{title}</summary>";
        bodyBuilder(this);
        Content.FormattedBody += "</details>";
        return this;
    }

    public MessageBuilder WithTable(Action<TableBuilder> tableBuilder) {
        var tb = new TableBuilder(this);
        this.WithHtmlTag("table", msb => tableBuilder(tb));
        return this;
    }

    public class TableBuilder(MessageBuilder msb) {
        public TableBuilder WithTitle(string title, int colspan) {
            msb.Content.Body += title + "\n";
            msb.Content.FormattedBody += $"<thead><tr><th colspan=\"{colspan}\">{title}</th></tr></thead>";
            return this;
        }

        public TableBuilder WithRow(Action<RowBuilder> rowBuilder) {
            var rb = new RowBuilder(msb);
            msb.WithHtmlTag("tr", msb => rowBuilder(rb)).WithBody("\n");
            return this;
        }

        public class RowBuilder(MessageBuilder msb) {
            public RowBuilder WithCell(string content, Dictionary<string, string>? attributes = null) {
                msb.Content.Body += content + "\n";
                msb.Content.FormattedBody += $"<td>{content}</td>\t";
                return this;
            }
        }
    }
}