aboutsummaryrefslogtreecommitdiff
path: root/main/src/ui/conversation_summary/content_item_widget_factory.vala
blob: 54283e75d791e5209b894f0913604ea996e44612 (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
using Gee;
using Gdk;
using Gtk;
using Pango;
using Xmpp;

using Dino.Entities;

namespace Dino.Ui.ConversationSummary {

public class ContentItemWidgetFactory : Object {

    private StreamInteractor stream_interactor;
    private HashMap<string, WidgetGenerator> generators = new HashMap<string, WidgetGenerator>();

    public ContentItemWidgetFactory(StreamInteractor stream_interactor) {
        this.stream_interactor = stream_interactor;

        generators[MessageItem.TYPE] = new MessageItemWidgetGenerator(stream_interactor);
        generators[FileItem.TYPE] = new FileItemWidgetGenerator(stream_interactor);
    }

    public Widget? get_widget(ContentItem item) {
        WidgetGenerator? generator = generators[item.type_];
        if (generator != null) {
            return (Widget?) generator.get_widget(item);
        }
        return null;
    }

    public void register_widget_generator(WidgetGenerator generator) {
        generators[generator.handles_type] = generator;
    }
}

public interface WidgetGenerator : Object {
    public abstract string handles_type { get; set; }
    public abstract Object get_widget(ContentItem item);
}

public class MessageItemWidgetGenerator : WidgetGenerator, Object {

    public string handles_type { get; set; default=FileItem.TYPE; }

    private StreamInteractor stream_interactor;

    public MessageItemWidgetGenerator(StreamInteractor stream_interactor) {
        this.stream_interactor = stream_interactor;
    }

    public Object get_widget(ContentItem item) {
        MessageItem message_item = item as MessageItem;
        Conversation conversation = message_item.conversation;
        Message message = message_item.message;

        Label label = new Label("") { use_markup=true, xalign=0, selectable=true, wrap=true, wrap_mode=Pango.WrapMode.WORD_CHAR, vexpand=true, visible=true };
        string markup_text = message.body;
        if (markup_text.length > 10000) {
            markup_text = markup_text.substring(0, 10000) + " [" + _("Message too long") + "]";
        }
        if (message_item.message.body.has_prefix("/me")) {
            markup_text = markup_text.substring(3);
        }

        if (conversation.type_ == Conversation.Type.GROUPCHAT) {
            markup_text = Util.parse_add_markup(markup_text, conversation.nickname, true, true);
        } else {
            markup_text = Util.parse_add_markup(markup_text, null, true, true);
        }

        if (message_item.message.body.has_prefix("/me")) {
            string display_name = Util.get_participant_display_name(stream_interactor, conversation, message.from);
            update_me_style(stream_interactor, message.real_jid ?? message.from, display_name, conversation.account, label, markup_text);
            label.realize.connect(() => update_me_style(stream_interactor, message.real_jid ?? message.from, display_name, conversation.account, label, markup_text));
            label.style_updated.connect(() => update_me_style(stream_interactor, message.real_jid ?? message.from, display_name, conversation.account, label, markup_text));
        }

        int only_emoji_count = Util.get_only_emoji_count(markup_text);
        if (only_emoji_count != -1) {
            string size_str = only_emoji_count < 5 ? "xx-large" : "large";
            markup_text = @"<span size=\'$size_str\'>" + markup_text + "</span>";
        }

        label.label = markup_text;
        return label;
    }

    public static void update_me_style(StreamInteractor stream_interactor, Jid jid, string display_name, Account account, Label label, string action_text) {
        string color = Util.get_name_hex_color(stream_interactor, account, jid, Util.is_dark_theme(label));
        label.label = @"<span color=\"#$(color)\">$(Markup.escape_text(display_name))</span>" + action_text;
    }
}

public class FileItemWidgetGenerator : WidgetGenerator, Object {

    public StreamInteractor stream_interactor;
    public string handles_type { get; set; default=FileItem.TYPE; }

    private const int MAX_HEIGHT = 300;
    private const int MAX_WIDTH = 600;

    public FileItemWidgetGenerator(StreamInteractor stream_interactor) {
        this.stream_interactor = stream_interactor;
    }

    public Object get_widget(ContentItem item) {
        FileItem file_item = item as FileItem;
        FileTransfer transfer = file_item.file_transfer;

        return new FileWidget(stream_interactor, transfer) { visible=true };
    }
}

}