anotherim-desktop/main/src/ui/conversation_selector/conversation_row.vala

191 lines
7.3 KiB
Vala
Raw Normal View History

2017-03-02 14:37:32 +00:00
using Gee;
using Gdk;
using Gtk;
using Pango;
using Dino.Entities;
namespace Dino.Ui.ConversationSelector {
2017-08-17 19:24:01 +00:00
[GtkTemplate (ui = "/im/dino/conversation_selector/conversation_row.ui")]
2017-03-02 14:37:32 +00:00
public abstract class ConversationRow : ListBoxRow {
public signal void closed();
2017-03-10 17:07:28 +00:00
[GtkChild] protected Image image;
[GtkChild] protected Label name_label;
[GtkChild] protected Label time_label;
[GtkChild] protected Label nick_label;
[GtkChild] protected Label message_label;
2017-03-10 17:07:28 +00:00
[GtkChild] protected Button x_button;
[GtkChild] protected Revealer time_revealer;
[GtkChild] protected Revealer xbutton_revealer;
2017-03-10 17:07:28 +00:00
[GtkChild] public Revealer main_revealer;
2017-03-02 14:37:32 +00:00
public Conversation conversation { get; private set; }
protected const int AVATAR_SIZE = 40;
protected Message? last_message;
2017-03-02 14:37:32 +00:00
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(close_conversation);
2017-09-19 22:26:04 +00:00
conversation.notify["read-up-to"].connect(update_read);
stream_interactor.connection_manager.connection_state_changed.connect(update_avatar);
2017-03-02 14:37:32 +00:00
update_name_label();
update_avatar();
message_received();
2017-03-02 14:37:32 +00:00
}
public void update() {
update_time_label();
2017-03-02 14:37:32 +00:00
}
public void message_received(Entities.Message? m = null) {
last_message = stream_interactor.get_module(MessageStorage.IDENTITY).get_last_message(conversation) ?? m;
update_message_label();
update_time_label();
2017-09-19 21:23:12 +00:00
update_read();
2017-03-02 14:37:32 +00:00
}
public virtual void on_show_received(Show presence) {
update_avatar();
}
2017-03-02 14:37:32 +00:00
public void update_avatar() {
bool self_online = stream_interactor.connection_manager.get_state(conversation.account) == ConnectionManager.ConnectionState.CONNECTED;
bool counterpart_online = stream_interactor.get_module(PresenceManager.IDENTITY).get_full_jids(conversation.counterpart, conversation.account) != null;
bool greyscale = !self_online || !counterpart_online;
Idle.add(() => {
Pixbuf pixbuf = ((new AvatarGenerator(AVATAR_SIZE, AVATAR_SIZE, image.scale_factor))
.set_greyscale(greyscale)
.draw_conversation(stream_interactor, conversation));
Util.image_set_from_scaled_pixbuf(image, pixbuf, image.get_scale_factor());
return false;
});
2017-03-02 14:37:32 +00:00
}
protected void update_name_label(string? new_name = null) {
name_label.label = Util.get_conversation_display_name(stream_interactor, conversation);
2017-03-02 14:37:32 +00:00
}
protected void update_time_label(DateTime? new_time = null) {
if (last_message != null) {
time_label.visible = true;
time_label.label = get_relative_time(last_message.time.to_local());
2017-03-02 14:37:32 +00:00
}
}
protected virtual void update_message_label() {
if (last_message != null) {
2017-03-02 14:37:32 +00:00
message_label.visible = true;
message_label.label = last_message.body.replace("\n", " ");
2017-03-02 14:37:32 +00:00
}
}
2017-09-19 21:23:12 +00:00
protected void update_read() {
bool read_was = read;
read = last_message == null || (conversation.read_up_to != null && last_message.equals(conversation.read_up_to));
if (read == read_was) return;
2017-03-02 14:37:32 +00:00
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)));
nick_label.attributes.filter((attr) => attr.equal(attr_weight_new(Weight.BOLD)));
2017-03-02 14:37:32 +00:00
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));
nick_label.attributes.insert(attr_weight_new(Weight.BOLD));
2017-03-02 14:37:32 +00:00
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;
nick_label.label = nick_label.label;
2017-03-02 14:37:32 +00:00
message_label.label = message_label.label;
}
2017-03-30 23:17:01 +00:00
protected Box get_fulljid_box(Jid full_jid) {
Box box = new Box(Orientation.HORIZONTAL, 5) { visible=true };
Show show = stream_interactor.get_module(PresenceManager.IDENTITY).get_last_show(full_jid, conversation.account);
Image image = new Image() { visible=true };
if (show.as == Show.AWAY) {
image.set_from_icon_name("dino-status-away", IconSize.SMALL_TOOLBAR);
} else if (show.as == Show.XA || show.as == Show.DND) {
image.set_from_icon_name("dino-status-dnd", IconSize.SMALL_TOOLBAR);
} else if (show.as == Show.CHAT) {
image.set_from_icon_name("dino-status-chat", IconSize.SMALL_TOOLBAR);
} else {
image.set_from_icon_name("dino-status-online", IconSize.SMALL_TOOLBAR);
}
box.add(image);
Label resource = new Label(full_jid.resourcepart) { visible=true };
resource.xalign = 0;
box.add(resource);
box.show_all();
return box;
}
private void close_conversation() {
2017-03-02 14:37:32 +00:00
main_revealer.set_transition_type(RevealerTransitionType.SLIDE_UP);
main_revealer.set_reveal_child(false);
closed();
2017-03-02 14:37:32 +00:00
main_revealer.notify["child-revealed"].connect(() => {
stream_interactor.get_module(ConversationManager.IDENTITY).close_conversation(conversation);
2017-03-02 14:37:32 +00:00
});
}
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) {
2017-08-31 16:40:58 +00:00
DateTime now = new DateTime.now_utc();
2017-03-02 14:37:32 +00:00
TimeSpan timespan = now.difference(datetime);
if (timespan > 365 * TimeSpan.DAY) {
return datetime.get_year().to_string();
} else if (timespan > 7 * TimeSpan.DAY) {
// Day and month
// xgettext:no-c-format
return datetime.format(_("%b %d"));
2017-03-02 14:37:32 +00:00
} else if (timespan > 2 * TimeSpan.DAY) {
return datetime.format("%a");
} else if (timespan > 1 * TimeSpan.DAY) {
return _("Yesterday");
2017-03-02 14:37:32 +00:00
} else if (timespan > 9 * TimeSpan.MINUTE) {
return datetime.format(Util.is_24h_format() ?
/* xgettext:no-c-format */ /* Time in 24h format (w/o seconds) */ _("%H%M") :
/* xgettext:no-c-format */ /* Time in 12h format (w/o seconds) */ _("%l%M %p"));
2017-03-02 14:37:32 +00:00
} else if (timespan > 1 * TimeSpan.MINUTE) {
ulong mins = (ulong) (timespan.abs() / TimeSpan.MINUTE);
return n("%i min ago", "%i mins ago", mins).printf(mins);
2017-03-02 14:37:32 +00:00
} else {
return _("Just now");
2017-03-02 14:37:32 +00:00
}
}
}
2017-03-10 17:07:28 +00:00
2017-03-02 14:37:32 +00:00
}