Tooth/src/Widgets/RichLabelContainer.vala

131 lines
3.3 KiB
Vala

using Gtk;
using Gee;
public class Tooth.Widgets.RichLabelContainer : Adw.Bin {
Button widget;
Box button_child;
string on_click_url = null;
public weak ArrayList<API.Mention>? mentions;
construct {
widget = new Button ();
button_child = new Box(Orientation.HORIZONTAL, 0);
widget.child = button_child;
widget.halign = Align.START;
child = widget;
widget.clicked.connect (on_click);
}
public void set_label (string text, string? url, Gee.HashMap<string, string>? emojis, bool force_no_style = false, bool should_markup = false) {
if (text.contains(":") && emojis != null) {
string[] labelss = text.split (":");
// Whether the last item was an emoji
bool was_emoji = false;
// Whether its the first item
bool is_first = labelss[0].get_char() != ':';
// The last created label
Label? last_label = null;
foreach (unowned string str in labelss) {
// If str is an available emoji
if (emojis.has_key(str)) {
button_child.append(new Widgets.Emoji(emojis.get(str)));
was_emoji = true;
} else {
// The label
// if the last item was not an emoji
// and its not the first item, prefix
// it with a ":"
// This way if someone has a name that
// includes ":" (and its not an emoji)
// we re-create the original string
string txt = (!was_emoji && !is_first ? ":" : "") + str;
// If the last label was not an emoji
// append the new label to it
// instead of creating a new one
if (last_label != null && !was_emoji) {
last_label.label = last_label.label + txt;
} else {
var tmp_child = new Label ("") {
xalign = 0,
wrap = true,
wrap_mode = Pango.WrapMode.WORD_CHAR,
justify = Justification.LEFT,
single_line_mode = false,
use_markup = false
};
tmp_child.label = txt;
button_child.append(tmp_child);
}
was_emoji = false;
}
is_first = false;
}
} else {
var tmp_child = new Label ("") {
xalign = 0,
wrap = true,
wrap_mode = Pango.WrapMode.WORD_CHAR,
justify = Justification.LEFT,
single_line_mode = false,
use_markup = should_markup
};
tmp_child.label = text;
button_child.append(tmp_child);
}
// if there's no url
// make the button look
// like a label
if (url ==null || force_no_style) {
widget.add_css_class("ttl-label-emoji-no-click");
}
on_click_url = url;
}
protected void on_click () {
if (on_click_url == null) return;
if (mentions != null){
mentions.@foreach (mention => {
if (on_click_url == mention.url)
mention.open ();
return true;
});
}
if ("/tags/" in on_click_url) {
var encoded = on_click_url.split ("/tags/")[1];
var tag = Soup.URI.decode (encoded);
app.main_window.open_view (new Views.Hashtag (tag));
return;
}
if (should_resolve_url (on_click_url)) {
accounts.active.resolve.begin (on_click_url, (obj, res) => {
try {
accounts.active.resolve.end (res).open ();
}
catch (Error e) {
warning (@"Failed to resolve URL \"$on_click_url\":");
warning (e.message);
Host.open_uri (on_click_url);
}
});
}
else {
Host.open_uri (on_click_url);
}
return;
}
public static bool should_resolve_url (string url) {
return settings.aggressive_resolving || "@" in url || "user" in url;
}
}