dino/main/src/ui/conversation_selector/conversation_row.vala

161 lines
5.1 KiB
Vala

using Gee;
using Gdk;
using Gtk;
using Pango;
using Xmpp;
using Dino.Entities;
namespace Dino.Ui.ConversationSelector {
[GtkTemplate (ui = "/org/dino-im/conversation_selector/conversation_row.ui")]
public abstract class ConversationRow : ListBoxRow {
[GtkChild] protected Image image;
[GtkChild] private Label name_label;
[GtkChild] private Label time_label;
[GtkChild] private Label message_label;
[GtkChild] protected Button x_button;
[GtkChild] private Revealer time_revealer;
[GtkChild] private Revealer xbutton_revealer;
[GtkChild] public Revealer main_revealer;
public Conversation conversation { get; private set; }
protected const int AVATAR_SIZE = 40;
protected string display_name;
protected string message;
protected DateTime time;
protected bool read = true;
protected StreamInteractor stream_interactor;
construct {
name_label.attributes = new AttrList();
}
public ConversationRow(StreamInteractor stream_interactor, Conversation conversation) {
this.conversation = conversation;
this.stream_interactor = stream_interactor;
x_button.clicked.connect(on_x_button_clicked);
update_name(Util.get_conversation_display_name(stream_interactor, conversation));
Entities.Message message = MessageManager.get_instance(stream_interactor).get_last_message(conversation);
if (message != null) {
message_received(message);
}
}
public void update() {
update_time();
}
public void message_received(Entities.Message message) {
update_message(message.body.replace("\n", " "));
update_time(message.time.to_local());
}
public void set_avatar(Pixbuf pixbuf, int scale_factor = 1) {
Util.image_set_from_scaled_pixbuf(image, pixbuf, scale_factor);
image.queue_draw();
}
public void mark_read() {
update_read(true);
}
public void mark_unread() {
update_read(false);
}
public abstract void on_show_received(Show presence);
public abstract void network_connection(bool connected);
protected void update_name(string? new_name = null) {
if (new_name != null) {
display_name = new_name;
}
name_label.label = display_name;
}
protected void update_time(DateTime? new_time = null) {
time_label.visible = true;
if (new_time != null) {
time = new_time;
}
if (time != null) {
time_label.label = get_relative_time(time);
}
}
protected void update_message(string? new_message = null) {
if (new_message != null) {
message = new_message;
}
if (message != null) {
message_label.visible = true;
message_label.label = message;
}
}
protected void update_read(bool read) {
this.read = read;
if (read) {
name_label.attributes.filter((attr) => attr.equal(attr_weight_new(Weight.BOLD)));
time_label.attributes.filter((attr) => attr.equal(attr_weight_new(Weight.BOLD)));
message_label.attributes.filter((attr) => attr.equal(attr_weight_new(Weight.BOLD)));
} else {
name_label.attributes.insert(attr_weight_new(Weight.BOLD));
time_label.attributes.insert(attr_weight_new(Weight.BOLD));
message_label.attributes.insert(attr_weight_new(Weight.BOLD));
}
name_label.label = name_label.label; // TODO initializes redrawing, which would otherwise not happen. nicer?
time_label.label = time_label.label;
message_label.label = message_label.label;
}
private void on_x_button_clicked() {
main_revealer.set_transition_type(RevealerTransitionType.SLIDE_UP);
main_revealer.set_reveal_child(false);
main_revealer.notify["child-revealed"].connect(() => {
conversation.active = false;
});
}
public override void state_flags_changed(StateFlags flags) {
StateFlags curr_flags = get_state_flags();
if ((curr_flags & StateFlags.PRELIGHT) != 0) {
time_revealer.set_reveal_child(false);
xbutton_revealer.set_reveal_child(true);
} else {
time_revealer.set_reveal_child(true);
xbutton_revealer.set_reveal_child(false);
}
}
private static string get_relative_time(DateTime datetime) {
DateTime now = new DateTime.now_local();
TimeSpan timespan = now.difference(datetime);
if (timespan > 365 * TimeSpan.DAY) {
return datetime.get_year().to_string();
} else if (timespan > 7 * TimeSpan.DAY) {
return datetime.format("%d.%m");
} else if (timespan > 2 * TimeSpan.DAY) {
return datetime.format("%a");
} else if (timespan > 1 * TimeSpan.DAY) {
return "Yesterday";
} else if (timespan > 9 * TimeSpan.MINUTE) {
return datetime.format("%H:%M");
} else if (timespan > 1 * TimeSpan.MINUTE) {
return (timespan / TimeSpan.MINUTE).to_string() + " min ago";
} else {
return "Just now";
}
}
}
}