aboutsummaryrefslogtreecommitdiff
path: root/src/ChatMessage.cpp
blob: e4404096c26730793f3ec6bf7c174a38a4d694b8 (plain)
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
#include "../include/ChatMessage.hpp"
#include <dchat/IncomingMessage.hpp>
#include <assert.h>

namespace dchat
{
    static void appendRichText(Gtk::TextView *textView, Glib::RefPtr<Gtk::TextBuffer> buffer, Gtk::TextIter iter, const Glib::ustring &text)
    {
        parseIncomingMessage(text.data(), text.bytes(), [textView, &text, &iter, &buffer](IncomingMessagePart messagePart)
        {
            switch(messagePart.type)
            {
                case IncomingMessagePart::Type::TEXT:
                {
                    iter = buffer->insert(iter, text.data() + messagePart.textRange.start, text.data() + messagePart.textRange.end);
                    break;
                }
                case IncomingMessagePart::Type::EMOJI:
                {
                    auto anchor = Gtk::TextChildAnchor::create();
                    iter = buffer->insert_child_anchor(iter, anchor);
                    auto image = Gtk::manage(new DynamicImage());
                    image->url = text.substr(messagePart.textRange.start, messagePart.textRange.length());
                    image->set_size_request(35, 35);
                    textView->add_child_at_anchor(*image, anchor);
                    break;
                }
                default:
                    assert(false);
                    break;
            }
        });
    }
    
    void applyRichText(Gtk::TextView *textView, const Glib::ustring &text)
    {
        auto buffer = textView->get_buffer();
        buffer->set_text("");
        appendRichText(textView, buffer, buffer->begin(), text);
    }

    ChatMessage::ChatMessage(const Glib::ustring &_username, const Glib::ustring &_text, uint32_t _timestampSeconds) : 
        username(_username),
        timestampSeconds(_timestampSeconds)
    {
        avatar.set_halign(Gtk::ALIGN_START);
        avatar.set_valign(Gtk::ALIGN_START);
        avatar.set_size_request(35, 35);

        username.set_selectable(true);
        username.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_START);
        username.get_style_context()->add_class("message-message-username");

        text.set_wrap_mode(Gtk::WRAP_WORD_CHAR);
        //text.set_halign(Gtk::ALIGN_START);
        //text.set_valign(Gtk::ALIGN_START);
        text.set_hexpand(true);
        text.set_editable(false);
        applyRichText(&text, _text);
        text.get_style_context()->add_class("message-message-text");

        attach(avatar, 0, 0, 1, 2);
        attach_next_to(username, avatar, Gtk::POS_RIGHT, 1, 1);
        attach_next_to(text, username, Gtk::POS_BOTTOM, 1, 1);
        get_style_context()->add_class("message-message");

        set_column_spacing(10);
        set_row_spacing(0);
        set_vexpand(false);
    }

    void ChatMessage::appendText(const Glib::ustring &_text)
    {
        auto buffer = text.get_buffer();
        // Optimized for single ascii characters, such as "\n"
        if(_text.bytes() == 1)
        {
            buffer->insert(buffer->end(), _text);
        }
        else
        {
            appendRichText(&text, buffer, buffer->end(), _text);
        }
    }
}