From 447464f4d1ac0c184764f103ac9e51f7ff2dce91 Mon Sep 17 00:00:00 2001 From: fiaxh Date: Sat, 14 Aug 2021 20:22:52 +0200 Subject: Display message delivery error, color text using theme colors fixes #672 --- main/data/theme.css | 8 +++ .../conversation_item_skeleton.vala | 13 +++++ .../conversation_content_view/message_widget.vala | 63 +++++++++++++++++----- main/src/ui/util/helper.vala | 30 +++++++++-- 4 files changed, 98 insertions(+), 16 deletions(-) (limited to 'main') diff --git a/main/data/theme.css b/main/data/theme.css index 454bd2c1..cf57ae96 100644 --- a/main/data/theme.css +++ b/main/data/theme.css @@ -86,6 +86,14 @@ window.dino-main .dino-conversation .message-box.edit-mode:hover { background: alpha(@theme_selected_bg_color, 0.12); } +window.dino-main .dino-conversation .message-box.error { + background: alpha(@error_color, 0.1); +} + +window.dino-main .dino-conversation .message-box.error:hover { + background: alpha(@error_color, 0.12); +} + window.dino-main .file-box-outer, window.dino-main .call-box-outer { background: @theme_base_color; diff --git a/main/src/ui/conversation_content_view/conversation_item_skeleton.vala b/main/src/ui/conversation_content_view/conversation_item_skeleton.vala index bcb6864e..343c6631 100644 --- a/main/src/ui/conversation_content_view/conversation_item_skeleton.vala +++ b/main/src/ui/conversation_content_view/conversation_item_skeleton.vala @@ -16,6 +16,7 @@ public class ConversationItemSkeleton : EventBox { public Conversation conversation { get; set; } public Plugins.MetaConversationItem item; public bool item_in_edit_mode { get; set; } + public Entities.Message.Marked item_mark { get; set; } public ContentMetaItem? content_meta_item = null; public Widget? widget = null; @@ -34,6 +35,10 @@ public class ConversationItemSkeleton : EventBox { item.bind_property("in-edit-mode", this, "item-in-edit-mode"); this.notify["item-in-edit-mode"].connect(update_edit_mode); + item.bind_property("mark", this, "item-mark", BindingFlags.SYNC_CREATE); + this.notify["item-mark"].connect(update_error_mode); + update_error_mode(); + widget = item.get_widget(Plugins.WidgetType.GTK) as Widget; if (widget != null) { widget.valign = Align.END; @@ -96,6 +101,14 @@ public class ConversationItemSkeleton : EventBox { this.get_style_context().remove_class("edit-mode"); } } + + private void update_error_mode() { + if (item_mark == Message.Marked.ERROR) { + this.get_style_context().add_class("error"); + } else { + this.get_style_context().remove_class("error"); + } + } } [GtkTemplate (ui = "/im/dino/Dino/conversation_content_view/item_metadata_header.ui")] diff --git a/main/src/ui/conversation_content_view/message_widget.vala b/main/src/ui/conversation_content_view/message_widget.vala index 44584709..93e48848 100644 --- a/main/src/ui/conversation_content_view/message_widget.vala +++ b/main/src/ui/conversation_content_view/message_widget.vala @@ -77,6 +77,12 @@ public class MessageItemWidget : SizeRequestBin { public signal void edit_cancelled(); public signal void edit_sent(string text); + enum AdditionalInfo { + NONE, + PENDING, + DELIVERY_FAILED + } + StreamInteractor stream_interactor; public ContentItem content_item; public Message.Marked marked { get; set; } @@ -84,6 +90,7 @@ public class MessageItemWidget : SizeRequestBin { Label label = new Label("") { use_markup=true, xalign=0, selectable=true, wrap=true, wrap_mode=Pango.WrapMode.WORD_CHAR, vexpand=true, visible=true }; MessageItemEditMode? edit_mode = null; ChatTextViewController? controller = null; + AdditionalInfo additional_info = AdditionalInfo.NONE; ulong realize_id = -1; ulong style_updated_id = -1; @@ -99,6 +106,34 @@ public class MessageItemWidget : SizeRequestBin { this.stream_interactor = stream_interactor; this.content_item = content_item; + Message message = ((MessageItem) content_item).message; + if (message.direction == Message.DIRECTION_SENT && !(message.marked in Message.MARKED_RECEIVED)) { + var binding = message.bind_property("marked", this, "marked"); + marked_notify_handler_id = this.notify["marked"].connect(() => { + // Currently "pending", but not anymore + if (additional_info == AdditionalInfo.PENDING && + message.marked != Message.Marked.SENDING && message.marked != Message.Marked.UNSENT) { + update_label(); + } + + // Currently "error", but not anymore + if (additional_info == AdditionalInfo.DELIVERY_FAILED && message.marked != Message.Marked.ERROR) { + update_label(); + } + + // Currently not error, but should be + if (additional_info != AdditionalInfo.DELIVERY_FAILED && message.marked == Message.Marked.ERROR) { + update_label(); + } + + // Nothing bad can happen anymore + if (message.marked in Message.MARKED_RECEIVED) { + binding.unbind(); + this.disconnect(marked_notify_handler_id); + } + }); + } + update_label(); } @@ -181,32 +216,34 @@ public class MessageItemWidget : SizeRequestBin { markup_text = @"" + markup_text + ""; } - string gray_color = Util.is_dark_theme(label) ? "#808080" : "#909090"; + string gray_color = Util.rgba_to_hex(Util.get_label_pango_class_color(label, "dim-label")); if (message.edit_to != null) { - markup_text += " (%s)".printf(gray_color, _("edited")); + markup_text += " (%s)".printf(gray_color, _("edited")); theme_dependent = true; } - // Append "pending..." iff message has not been sent yet + // Append message status info + additional_info = AdditionalInfo.NONE; if (message.direction == Message.DIRECTION_SENT && (message.marked == Message.Marked.SENDING || message.marked == Message.Marked.UNSENT)) { + // Append "pending..." iff message has not been sent yet if (message.time.compare(new DateTime.now_utc().add_seconds(-10)) < 0) { - markup_text += " %s".printf(gray_color, "pending…"); - - // Update the label as soon as the sent state changes - var binding = message.bind_property("marked", this, "marked"); - marked_notify_handler_id = this.notify["marked"].connect(() => { - binding.unbind(); - this.disconnect(marked_notify_handler_id); - update_label(); - }); + markup_text += " %s".printf(gray_color, _("pending…")); + theme_dependent = true; + additional_info = AdditionalInfo.PENDING; } else { int time_diff = (- (int) message.time.difference(new DateTime.now_utc()) / 1000); Timeout.add(10000 - time_diff, () => { - update_label(); + update_label(); return false; }); } + } else if (message.direction == Message.DIRECTION_SENT && message.marked == Message.Marked.ERROR) { + // Append "delivery failed" if there was a server error + string error_color = Util.rgba_to_hex(Util.get_label_pango_color(label, "@error_color")); + markup_text += " %s".printf(error_color, _("delivery failed")); + theme_dependent = true; + additional_info = AdditionalInfo.DELIVERY_FAILED; } if (theme_dependent && realize_id == -1) { diff --git a/main/src/ui/util/helper.vala b/main/src/ui/util/helper.vala index 07c81167..d5967ef3 100644 --- a/main/src/ui/util/helper.vala +++ b/main/src/ui/util/helper.vala @@ -154,10 +154,33 @@ public static void image_set_from_scaled_pixbuf(Image image, Gdk.Pixbuf pixbuf, image.set_from_surface(surface); } +public static Gdk.RGBA get_label_pango_color(Label label, string css_color) { + Gtk.CssProvider provider = force_color(label, css_color); + Gdk.RGBA color_rgba = label.get_style_context().get_color(StateFlags.NORMAL); + label.get_style_context().remove_provider(provider); + return color_rgba; +} + +public static Gdk.RGBA get_label_pango_class_color(Label label, string css_class) { + label.get_style_context().add_class(css_class); + Gdk.RGBA color_rgba = label.get_style_context().get_color(StateFlags.NORMAL); + label.get_style_context().remove_class(css_class); + return color_rgba; +} + +public static string rgba_to_hex(Gdk.RGBA rgba) { + return "#%02x%02x%02x%02x".printf( + (uint)(Math.round(rgba.red*255)), + (uint)(Math.round(rgba.green*255)), + (uint)(Math.round(rgba.blue*255)), + (uint)(Math.round(rgba.alpha*255))) + .up(); +} + private const string force_background_css = "%s { background-color: %s; }"; private const string force_color_css = "%s { color: %s; }"; -public static void force_css(Gtk.Widget widget, string css) { +public static Gtk.CssProvider force_css(Gtk.Widget widget, string css) { var p = new Gtk.CssProvider(); try { p.load_from_data(css); @@ -165,14 +188,15 @@ public static void force_css(Gtk.Widget widget, string css) { } catch (GLib.Error err) { // handle err } + return p; } public static void force_background(Gtk.Widget widget, string color, string selector = "*") { force_css(widget, force_background_css.printf(selector, color)); } -public static void force_color(Gtk.Widget widget, string color, string selector = "*") { - force_css(widget, force_color_css.printf(selector, color)); +public static Gtk.CssProvider force_color(Gtk.Widget widget, string color, string selector = "*") { + return force_css(widget, force_color_css.printf(selector, color)); } public static void force_error_color(Gtk.Widget widget, string selector = "*") { -- cgit v1.2.3-70-g09d2