diff options
-rw-r--r-- | libdino/src/application.vala | 4 | ||||
-rw-r--r-- | libdino/src/entity/conversation.vala | 2 | ||||
-rw-r--r-- | libdino/src/service/avatar_manager.vala | 35 | ||||
-rw-r--r-- | libdino/src/service/conversation_manager.vala | 57 | ||||
-rw-r--r-- | libdino/src/service/registration.vala | 25 | ||||
-rw-r--r-- | main/data/conversation_summary/view.ui | 3 | ||||
-rw-r--r-- | main/data/theme.css | 4 | ||||
-rw-r--r-- | main/src/ui/avatar_image.vala | 4 | ||||
-rw-r--r-- | main/src/ui/conversation_selector/conversation_selector.vala | 2 | ||||
-rw-r--r-- | main/src/ui/conversation_summary/content_item_widget_factory.vala | 1 | ||||
-rw-r--r-- | main/src/ui/conversation_summary/conversation_item_skeleton.vala | 79 | ||||
-rw-r--r-- | main/src/ui/conversation_summary/conversation_view.vala | 111 | ||||
-rw-r--r-- | xmpp-vala/src/core/xmpp_log.vala | 4 | ||||
-rw-r--r-- | xmpp-vala/src/core/xmpp_stream.vala | 5 | ||||
-rw-r--r-- | xmpp-vala/src/module/xep/0368_srv_records_tls.vala | 1 |
15 files changed, 183 insertions, 154 deletions
diff --git a/libdino/src/application.vala b/libdino/src/application.vala index 7b19a9e9..da098fb4 100644 --- a/libdino/src/application.vala +++ b/libdino/src/application.vala @@ -26,15 +26,15 @@ public interface Dino.Application : GLib.Application { this.settings = new Dino.Entities.Settings.from_db(db); this.stream_interactor = new StreamInteractor(db); - AvatarManager.start(stream_interactor, db); MessageProcessor.start(stream_interactor, db); MessageStorage.start(stream_interactor, db); CounterpartInteractionManager.start(stream_interactor); PresenceManager.start(stream_interactor); BlockingManager.start(stream_interactor); + ConversationManager.start(stream_interactor, db); MucManager.start(stream_interactor); + AvatarManager.start(stream_interactor, db); RosterManager.start(stream_interactor, db); - ConversationManager.start(stream_interactor, db); ChatInteraction.start(stream_interactor); FileManager.start(stream_interactor, db); ContentItemStore.start(stream_interactor, db); diff --git a/libdino/src/entity/conversation.vala b/libdino/src/entity/conversation.vala index 9e8a3406..0537ee61 100644 --- a/libdino/src/entity/conversation.vala +++ b/libdino/src/entity/conversation.vala @@ -136,7 +136,7 @@ public class Conversation : Object { } public static bool equals_func(Conversation conversation1, Conversation conversation2) { - return conversation1.counterpart.equals(conversation2.counterpart) && conversation1.account.equals(conversation2.account); + return conversation1.counterpart.equals(conversation2.counterpart) && conversation1.account.equals(conversation2.account) && conversation1.type_ == conversation2.type_; } public static uint hash_func(Conversation conversation) { diff --git a/libdino/src/service/avatar_manager.vala b/libdino/src/service/avatar_manager.vala index 9510389f..c9c078ab 100644 --- a/libdino/src/service/avatar_manager.vala +++ b/libdino/src/service/avatar_manager.vala @@ -53,6 +53,8 @@ public class AvatarManager : StreamInteractionModule, Object { Pixbuf? image = yield avatar_storage.get_image(hash); if (image != null) { cached_pixbuf[hash] = image; + } else { + db.avatar.delete().with(db.avatar.hash, "=", hash).perform(); } return image; } @@ -69,7 +71,12 @@ public class AvatarManager : StreamInteractionModule, Object { } public async Pixbuf? get_avatar(Account account, Jid jid) { - string? hash = get_avatar_hash(account, jid); + Jid jid_ = jid; + if (!stream_interactor.get_module(MucManager.IDENTITY).is_groupchat_occupant(jid, account)) { + jid_ = jid.bare_jid; + } + + string? hash = get_avatar_hash(account, jid_); if (hash != null) { return yield get_avatar_by_hash(hash); } @@ -77,15 +84,11 @@ public class AvatarManager : StreamInteractionModule, Object { } private string? get_avatar_hash(Account account, Jid jid) { - Jid jid_ = jid; - if (!stream_interactor.get_module(MucManager.IDENTITY).is_groupchat_occupant(jid, account)) { - jid_ = jid.bare_jid; - } - string? user_avatars_id = user_avatars[jid_]; + string? user_avatars_id = user_avatars[jid]; if (user_avatars_id != null) { return user_avatars_id; } - string? vcard_avatars_id = vcard_avatars[jid_]; + string? vcard_avatars_id = vcard_avatars[jid]; if (vcard_avatars_id != null) { return vcard_avatars_id; } @@ -122,13 +125,17 @@ public class AvatarManager : StreamInteractionModule, Object { on_vcard_avatar_received(account, jid, id) ); - user_avatars = db.get_avatar_hashes(Source.USER_AVATARS); - foreach (Jid jid in user_avatars.keys) { - on_user_avatar_received(account, jid, user_avatars[jid]); + foreach (var entry in db.get_avatar_hashes(Source.USER_AVATARS).entries) { + on_user_avatar_received(account, entry.key, entry.value); } - vcard_avatars = db.get_avatar_hashes(Source.VCARD); - foreach (Jid jid in vcard_avatars.keys) { - on_vcard_avatar_received(account, jid, vcard_avatars[jid]); + foreach (var entry in db.get_avatar_hashes(Source.VCARD).entries) { + // FIXME: remove. temporary to remove falsely saved avatars. + if (stream_interactor.get_module(MucManager.IDENTITY).is_groupchat(entry.key, account)) { + db.avatar.delete().with(db.avatar.jid, "=", entry.key.to_string()).perform(); + continue; + } + + on_vcard_avatar_received(account, entry.key, entry.value); } } @@ -148,7 +155,7 @@ public class AvatarManager : StreamInteractionModule, Object { private void on_vcard_avatar_received(Account account, Jid jid, string id) { if (!vcard_avatars.has_key(jid) || vcard_avatars[jid] != id) { vcard_avatars[jid] = id; - if (!jid.is_full()) { // don't save muc avatars + if (!jid.is_full()) { // don't save MUC occupant avatars db.set_avatar_hash(jid, id, Source.VCARD); } } diff --git a/libdino/src/service/conversation_manager.vala b/libdino/src/service/conversation_manager.vala index 77205c57..b1e8d8a8 100644 --- a/libdino/src/service/conversation_manager.vala +++ b/libdino/src/service/conversation_manager.vala @@ -14,7 +14,7 @@ public class ConversationManager : StreamInteractionModule, Object { private StreamInteractor stream_interactor; private Database db; - private HashMap<Account, HashMap<Jid, Conversation>> conversations = new HashMap<Account, HashMap<Jid, Conversation>>(Account.hash_func, Account.equals_func); + private HashMap<Account, HashMap<Jid, Gee.List<Conversation>>> conversations = new HashMap<Account, HashMap<Jid, Gee.List<Conversation>>>(Account.hash_func, Account.equals_func); public static void start(StreamInteractor stream_interactor, Database db) { ConversationManager m = new ConversationManager(stream_interactor, db); @@ -33,15 +33,19 @@ public class ConversationManager : StreamInteractionModule, Object { public Conversation create_conversation(Jid jid, Account account, Conversation.Type? type = null) { assert(conversations.has_key(account)); Jid store_jid = type == Conversation.Type.GROUPCHAT ? jid.bare_jid : jid; - if (conversations[account].has_key(store_jid)) { - conversations[account][store_jid].type_ = type; - return conversations[account][store_jid]; - } else { - Conversation conversation = new Conversation(jid, account, type); - add_conversation(conversation); - conversation.persist(db); - return conversation; + + // Do we already have a conversation for this jid? + foreach (var conversation in conversations[account][store_jid]) { + if (conversation.type_ == type) { + return conversation; + } } + + // Create a new converation + Conversation conversation = new Conversation(jid, account, type); + add_conversation(conversation); + conversation.persist(db); + return conversation; } public Conversation? get_conversation_for_message(Entities.Message message) { @@ -68,17 +72,27 @@ public class ConversationManager : StreamInteractionModule, Object { return ret; } - public Conversation? get_conversation(Jid jid, Account account) { + public Conversation? get_conversation(Jid jid, Account account, Conversation.Type? type = null) { if (conversations.has_key(account)) { - return conversations[account][jid]; + if (conversations[account].has_key(jid)) { + foreach (var conversation in conversations[account][jid]) { + if (type == null || conversation.type_ == type) { + return conversation; + } + } + } } return null; } public Conversation? get_conversation_by_id(int id) { - foreach (HashMap<Jid, Conversation> hm in conversations.values) { - foreach (Conversation conversation in hm.values) { - if (conversation.id == id) return conversation; + foreach (HashMap<Jid, Gee.List<Conversation>> hm in conversations.values) { + foreach (Gee.List<Conversation> hm2 in hm.values) { + foreach (Conversation conversation in hm2) { + if (conversation.id == id) { + return conversation; + } + } } } return null; @@ -88,8 +102,10 @@ public class ConversationManager : StreamInteractionModule, Object { Gee.List<Conversation> ret = new ArrayList<Conversation>(Conversation.equals_func); foreach (Account account_ in conversations.keys) { if (account != null && !account_.equals(account)) continue; - foreach (Conversation conversation in conversations[account_].values) { - if(conversation.active) ret.add(conversation); + foreach (Gee.List<Conversation> list in conversations[account_].values) { + foreach (var conversation in list) { + if(conversation.active) ret.add(conversation); + } } } return ret; @@ -112,7 +128,7 @@ public class ConversationManager : StreamInteractionModule, Object { } private void on_account_added(Account account) { - conversations[account] = new HashMap<Jid, Conversation>(Jid.hash_func, Jid.equals_func); + conversations[account] = new HashMap<Jid, ArrayList<Conversation>>(Jid.hash_func, Jid.equals_func); foreach (Conversation conversation in db.get_conversations(account)) { add_conversation(conversation); } @@ -153,7 +169,12 @@ public class ConversationManager : StreamInteractionModule, Object { } private void add_conversation(Conversation conversation) { - conversations[conversation.account][conversation.counterpart] = conversation; + if (!conversations[conversation.account].has_key(conversation.counterpart)) { + conversations[conversation.account][conversation.counterpart] = new ArrayList<Conversation>(Conversation.equals_func); + } + + conversations[conversation.account][conversation.counterpart].add(conversation); + if (conversation.active) { conversation_activated(conversation); } diff --git a/libdino/src/service/registration.vala b/libdino/src/service/registration.vala index 8cac355e..f2384f52 100644 --- a/libdino/src/service/registration.vala +++ b/libdino/src/service/registration.vala @@ -75,42 +75,53 @@ public class Register : StreamInteractionModule, Object{ Idle.add((owned)callback); } }); - Timeout.add_seconds(5, () => { + + stream.connect.begin(jid.domainpart, (_, res) => { + try { + stream.connect.end(res); + } catch (Error e) { + debug("Error connecting to stream: %s", e.message); + } if (callback != null) { Idle.add((owned)callback); } - return false; }); - stream.connect.begin(jid.domainpart); yield; + try { stream.disconnect(); } catch (Error e) {} return ret; } - public static async Xep.InBandRegistration.Form get_registration_form(Jid jid) { + public static async Xep.InBandRegistration.Form? get_registration_form(Jid jid) { XmppStream stream = new XmppStream(); stream.add_module(new Tls.Module()); stream.add_module(new Iq.Module()); stream.add_module(new Xep.SrvRecordsTls.Module()); stream.add_module(new Xep.InBandRegistration.Module()); - stream.connect.begin(jid.bare_jid.to_string()); Xep.InBandRegistration.Form? form = null; SourceFunc callback = get_registration_form.callback; + stream.stream_negotiated.connect(() => { if (callback != null) { Idle.add((owned)callback); } }); - Timeout.add_seconds(5, () => { + + stream.connect.begin(jid.domainpart, (_, res) => { + try { + stream.connect.end(res); + } catch (Error e) { + debug("Error connecting to stream: %s", e.message); + } if (callback != null) { Idle.add((owned)callback); } - return false; }); + yield; if (stream.negotiation_complete) { form = yield stream.get_module(Xep.InBandRegistration.Module.IDENTITY).get_from_server(stream, jid); diff --git a/main/data/conversation_summary/view.ui b/main/data/conversation_summary/view.ui index 90d3d7c1..51133890 100644 --- a/main/data/conversation_summary/view.ui +++ b/main/data/conversation_summary/view.ui @@ -19,14 +19,13 @@ <property name="visible">True</property> <child> <object class="GtkBox"> - <property name="margin">15</property> <property name="orientation">vertical</property> <property name="visible">True</property> <child> <object class="GtkBox" id="main"> + <property name="margin-bottom">15</property> <property name="expand">False</property> <property name="orientation">vertical</property> - <property name="spacing">15</property> <property name="visible">True</property> </object> </child> diff --git a/main/data/theme.css b/main/data/theme.css index 1969c80b..8a1b50ad 100644 --- a/main/data/theme.css +++ b/main/data/theme.css @@ -37,6 +37,10 @@ window.dino-main .dino-conversation .highlight-once { animation-name: highlight; } +window.dino-main .dino-conversation .message-box:hover { + background: alpha(@theme_fg_color, 0.04); +} + window.dino-main .dino-sidebar > frame { background: @insensitive_bg_color; border-left: 1px solid @borders; diff --git a/main/src/ui/avatar_image.vala b/main/src/ui/avatar_image.vala index c052270a..846bf0ff 100644 --- a/main/src/ui/avatar_image.vala +++ b/main/src/ui/avatar_image.vala @@ -5,8 +5,8 @@ using Xmpp; namespace Dino.Ui { public class AvatarImage : Misc { - public int height { get; set; default = 32; } - public int width { get; set; default = 32; } + public int height { get; set; default = 35; } + public int width { get; set; default = 35; } public bool allow_gray { get; set; default = true; } public Account account { get; private set; } public StreamInteractor stream_interactor { get; set; } diff --git a/main/src/ui/conversation_selector/conversation_selector.vala b/main/src/ui/conversation_selector/conversation_selector.vala index dd264206..290e297f 100644 --- a/main/src/ui/conversation_selector/conversation_selector.vala +++ b/main/src/ui/conversation_selector/conversation_selector.vala @@ -33,8 +33,6 @@ public class ConversationSelector : ListBox { } construct { - this.stream_interactor = stream_interactor; - get_style_context().add_class("sidebar"); set_filter_func(filter); set_header_func(header); diff --git a/main/src/ui/conversation_summary/content_item_widget_factory.vala b/main/src/ui/conversation_summary/content_item_widget_factory.vala index b784c91a..2415eb38 100644 --- a/main/src/ui/conversation_summary/content_item_widget_factory.vala +++ b/main/src/ui/conversation_summary/content_item_widget_factory.vala @@ -178,6 +178,7 @@ public class FileItemWidgetGenerator : WidgetGenerator, Object { grid.attach(image, 0, 0, 1, 1); EventBox event_box = new EventBox() { halign=Align.START, visible=true }; + event_box.events = EventMask.POINTER_MOTION_MASK; event_box.add(grid); event_box.enter_notify_event.connect(() => { toolbar_revealer.reveal_child = true; return false; }); event_box.leave_notify_event.connect(() => { toolbar_revealer.reveal_child = false; return false; }); diff --git a/main/src/ui/conversation_summary/conversation_item_skeleton.vala b/main/src/ui/conversation_summary/conversation_item_skeleton.vala index a4e45f7a..808bcf7a 100644 --- a/main/src/ui/conversation_summary/conversation_item_skeleton.vala +++ b/main/src/ui/conversation_summary/conversation_item_skeleton.vala @@ -7,22 +7,25 @@ using Dino.Entities; namespace Dino.Ui.ConversationSummary { -public class ConversationItemSkeleton : Box { +public class ConversationItemSkeleton : EventBox { private AvatarImage image = new AvatarImage() { margin_top=2, valign=Align.START, visible=true, allow_gray = false }; + public bool show_skeleton { get; set; } + public bool last_group_item { get; set; } + public StreamInteractor stream_interactor; public Conversation conversation { get; set; } - public ArrayList<Plugins.MetaConversationItem> items = new ArrayList<Plugins.MetaConversationItem>(); + public Plugins.MetaConversationItem item; - private Grid grid = new Grid() { visible=true }; - private HashMap<Plugins.MetaConversationItem, Widget> item_widgets = new HashMap<Plugins.MetaConversationItem, Widget>(); + private Box image_content_box = new Box(Orientation.HORIZONTAL, 8) { visible=true }; + private Box header_content_box = new Box(Orientation.VERTICAL, 0) { visible=true }; private DefaultSkeletonHeader default_header; public ConversationItemSkeleton(StreamInteractor stream_interactor, Conversation conversation, Plugins.MetaConversationItem item) { this.conversation = conversation; this.stream_interactor = stream_interactor; - Box image_content_box = new Box(Orientation.HORIZONTAL, 8) { visible=true }; + this.get_style_context().add_class("message-box"); if (item.requires_avatar) { image.set_jid(stream_interactor, item.jid, conversation.account); @@ -34,30 +37,44 @@ public class ConversationItemSkeleton : Box { default_header.name_label.visible = false; default_header.dot_label.visible = false; } - grid.attach(default_header, 0, 0, 1, 1); + header_content_box.add(default_header); } - add_meta_item(item); - image_content_box.add(grid); - this.add(image_content_box); - } - - public void add_meta_item(Plugins.MetaConversationItem item) { - items.add(item); + // add item + this.item = item; if (default_header != null) { default_header.add_item(item); } Widget? widget = item.get_widget(Plugins.WidgetType.GTK) as Widget; + widget.valign = Align.END; if (widget != null) { - grid.attach(widget, 0, items.size, 1, 1); - item_widgets[item] = widget; + header_content_box.add(widget); } - } - public void remove_meta_item(Plugins.MetaConversationItem item) { - item_widgets[item].destroy(); - item_widgets.unset(item); - items.remove(item); + image_content_box.add(header_content_box); + this.add(image_content_box); + + if (item.get_type().is_a(typeof(ContentMetaItem))) { + this.motion_notify_event.connect((event) => { + this.set_state_flags(StateFlags.PRELIGHT, false); + return false; + }); + this.enter_notify_event.connect((event) => { + this.set_state_flags(StateFlags.PRELIGHT, false); + return false; + }); + this.leave_notify_event.connect((event) => { + this.unset_state_flags(StateFlags.PRELIGHT); + return false; + }); + } + + this.notify["show-skeleton"].connect(update_margin); + this.notify["last-group-item"].connect(update_margin); + + this.show_skeleton = true; + this.last_group_item = true; + update_margin(); } public void update_time() { @@ -65,13 +82,29 @@ public class ConversationItemSkeleton : Box { default_header.update_time(); } } + + public void update_margin() { + image.visible = this.show_skeleton; + if (default_header != null) { + default_header.visible = this.show_skeleton; + } + image_content_box.margin_start = this.show_skeleton ? 15 : 58; + + if (this.show_skeleton && this.last_group_item) { + image_content_box.margin_top = 8; + image_content_box.margin_bottom = 8; + } else { + image_content_box.margin_top = 4; + image_content_box.margin_bottom = 4; + } + } } public class DefaultSkeletonHeader : Box { private Box box = new Box(Orientation.HORIZONTAL, 4) { visible=true }; - public Label name_label = new Label("") { use_markup=true, xalign=0, visible=true }; - public Label time_label = new Label("") { use_markup=true, xalign=0, visible=true }; - public Label dot_label = new Label("<span size='small'>·</span>") { use_markup=true, xalign=0, visible=true }; + public Label name_label = new Label("") { use_markup=true, valign=Align.START, xalign=0, visible=true }; + public Label time_label = new Label("") { use_markup=true, valign=Align.START, xalign=0, visible=true }; + public Label dot_label = new Label("<span size='small'>·</span>") { use_markup=true, valign=Align.START, xalign=0, visible=true }; public Image encryption_image = new Image(); public Image received_image = new Image(); diff --git a/main/src/ui/conversation_summary/conversation_view.vala b/main/src/ui/conversation_summary/conversation_view.vala index 3592a6c1..d73d012b 100644 --- a/main/src/ui/conversation_summary/conversation_view.vala +++ b/main/src/ui/conversation_summary/conversation_view.vala @@ -98,26 +98,19 @@ public class ConversationView : Box, Plugins.ConversationItemCollection, Plugins if (after_items.size == 40) { at_current_content = false; } - { - int h = 0, i = 0; - main.@foreach((widget) => { - if (i >= before_items.size) return; - ConversationItemSkeleton? sk = widget as ConversationItemSkeleton; - i += sk != null ? sk.items.size : 1; - int minimum_height, natural_height; - widget.get_preferred_height_for_width(main.get_allocated_width() - 2 * main.margin, out minimum_height, out natural_height); - h += minimum_height + 15; - }); - } + // Compute where to jump to for centered message, jump, highlight. reload_messages = false; Timeout.add(700, () => { int h = 0, i = 0; + bool @break = false; main.@foreach((widget) => { - if (i >= before_items.size) return; - ConversationItemSkeleton? sk = widget as ConversationItemSkeleton; - i += sk != null ? sk.items.size : 1; - h += widget.get_allocated_height() + 15; + if (widget == w || @break) { + @break = true; + return; + } + h += widget.get_allocated_height(); + i++; }); scrolled.vadjustment.value = h - scrolled.vadjustment.page_size * 1/3; w.get_style_context().add_class("highlight-once"); @@ -183,14 +176,12 @@ public class ConversationView : Box, Plugins.ConversationItemCollection, Plugins public void do_insert_item(Plugins.MetaConversationItem item) { lock (meta_items) { - if (!item.can_merge || !merge_back(item)) { - insert_new(item); + insert_new(item); + if (item as ContentMetaItem != null) { + content_items.add(item); } + meta_items.add(item); } - if (item as ContentMetaItem != null) { - content_items.add(item); - } - meta_items.add(item); inserted_item(item); } @@ -198,15 +189,12 @@ public class ConversationView : Box, Plugins.ConversationItemCollection, Plugins private void remove_item(Plugins.MetaConversationItem item) { ConversationItemSkeleton? skeleton = item_item_skeletons[item]; if (skeleton != null) { - if (skeleton.items.size > 1) { - skeleton.remove_meta_item(item); - } else { - widgets[item].destroy(); - widgets.unset(item); - skeleton.destroy(); - item_skeletons.remove(skeleton); - item_item_skeletons.unset(item); - } + widgets[item].destroy(); + widgets.unset(item); + skeleton.destroy(); + item_skeletons.remove(skeleton); + item_item_skeletons.unset(item); + content_items.remove(item); meta_items.remove(item); } @@ -242,41 +230,9 @@ public class ConversationView : Box, Plugins.ConversationItemCollection, Plugins widget.destroy(); } - private bool merge_back(Plugins.MetaConversationItem item) { - Plugins.MetaConversationItem? lower_item = meta_items.lower(item); - if (lower_item != null) { - ConversationItemSkeleton lower_skeleton = item_item_skeletons[lower_item]; - Plugins.MetaConversationItem lower_start_item = lower_skeleton.items[0]; - if (lower_start_item.can_merge && - item.display_time.difference(lower_start_item.display_time) < TimeSpan.MINUTE && - lower_start_item.jid.equals(item.jid) && - lower_start_item.encryption == item.encryption && - (item.mark == Message.Marked.WONTSEND) == (lower_start_item.mark == Message.Marked.WONTSEND)) { - lower_skeleton.add_meta_item(item); - - widgets[item] = widgets[lower_start_item]; - item_item_skeletons[item] = lower_skeleton; - - return true; - } - } - return false; - } - private Widget insert_new(Plugins.MetaConversationItem item) { Plugins.MetaConversationItem? lower_item = meta_items.lower(item); - // Does another skeleton need to be split? - if (lower_item != null) { - ConversationItemSkeleton lower_skeleton = item_item_skeletons[lower_item]; - if (lower_skeleton.items.size > 1) { - Plugins.MetaConversationItem lower_end_item = lower_skeleton.items[lower_skeleton.items.size - 1]; - if (item.sort_time.compare(lower_end_item.sort_time) < 0) { - split_at_time(lower_skeleton, item.sort_time); - } - } - } - // Fill datastructure ConversationItemSkeleton item_skeleton = new ConversationItemSkeleton(stream_interactor, conversation, item) { visible=true }; item_item_skeletons[item] = item_skeleton; @@ -297,6 +253,19 @@ public class ConversationView : Box, Plugins.ConversationItemCollection, Plugins widgets[item] = insert; main.reorder_child(insert, index); + if (lower_item != null) { + ConversationItemSkeleton lower_skeleton = item_item_skeletons[lower_item]; + Plugins.MetaConversationItem lower_start_item = lower_skeleton.item; + if (item.display_time != null && lower_start_item.display_time != null && + item.display_time.difference(lower_start_item.display_time) < TimeSpan.MINUTE && + lower_start_item.jid.equals(item.jid) && + lower_start_item.encryption == item.encryption && + (item.mark == Message.Marked.WONTSEND) == (lower_start_item.mark == Message.Marked.WONTSEND)) { + item_skeleton.show_skeleton = false; + lower_skeleton.last_group_item = false; + } + } + // If an item from the past was added, add everything between that item and the (post-)first present item if (index == 0) { Dino.Application app = Dino.Application.get_default(); @@ -313,24 +282,6 @@ public class ConversationView : Box, Plugins.ConversationItemCollection, Plugins return insert; } - private void split_at_time(ConversationItemSkeleton split_skeleton, DateTime time) { - bool already_divided = false; - int i = 0; - while(i < split_skeleton.items.size) { - Plugins.MetaConversationItem meta_item = split_skeleton.items[i]; - if (time.compare(meta_item.display_time) < 0) { - remove_item(meta_item); - if (!already_divided) { - insert_new(meta_item); - already_divided = true; - } else { - do_insert_item(meta_item); - } - } - i++; - } - } - private void on_upper_notify() { if (was_upper == null || scrolled.vadjustment.value > was_upper - was_page_size - 1) { // scrolled down or content smaller than page size if (at_current_content) { diff --git a/xmpp-vala/src/core/xmpp_log.vala b/xmpp-vala/src/core/xmpp_log.vala index b42cd30a..921899c4 100644 --- a/xmpp-vala/src/core/xmpp_log.vala +++ b/xmpp-vala/src/core/xmpp_log.vala @@ -110,13 +110,13 @@ public class XmppLog { public void node(string what, StanzaNode node) { if (should_log_node(node)) { - stderr.printf("%sXMPP %s [%s]%s\n%s\n", ANSI_COLOR_WHITE, what, ident, ANSI_COLOR_END, use_ansi ? node.to_ansi_string(hide_ns) : node.to_string()); + stderr.printf("%sXMPP %s [%s]%s\n%s\n", use_ansi ? ANSI_COLOR_WHITE : "", what, ident, use_ansi ? ANSI_COLOR_END : "", use_ansi ? node.to_ansi_string(hide_ns) : node.to_string()); } } public void str(string what, string str) { if (should_log_str(str)) { - stderr.printf("%sXMPP %s [%s]%s\n%s\n", ANSI_COLOR_WHITE, what, ident, ANSI_COLOR_END, str); + stderr.printf("%sXMPP %s [%s]%s\n%s\n", use_ansi ? ANSI_COLOR_WHITE : "", what, ident, use_ansi ? ANSI_COLOR_END : "", str); } } diff --git a/xmpp-vala/src/core/xmpp_stream.vala b/xmpp-vala/src/core/xmpp_stream.vala index aff0b216..4bf6e0db 100644 --- a/xmpp-vala/src/core/xmpp_stream.vala +++ b/xmpp-vala/src/core/xmpp_stream.vala @@ -60,6 +60,7 @@ public class XmppStream { stream = yield best_provider.connect(this); } if (stream == null) { + debug("Connecting to %s, xmpp-client, tcp (fallback)", this.remote_name.to_string()); stream = yield (new SocketClient()).connect_async(new NetworkService("xmpp-client", "tcp", this.remote_name.to_string())); } if (stream == null) { @@ -67,9 +68,10 @@ public class XmppStream { } reset_stream((!)stream); } catch (Error e) { - debug("[%p] Could not connect to server", this); + debug("[%p] Could not connect to server: %s", this, e.message); throw new IOStreamError.CONNECT(e.message); } + debug("Connected to %s", remote_name); yield loop(); } @@ -379,6 +381,7 @@ public class StartTlsConnectionProvider : ConnectionProvider { public async override IOStream? connect(XmppStream stream) { try { SocketClient client = new SocketClient(); + debug("Connecting to %s %i (starttls)", srv_target.get_hostname(), srv_target.get_port()); return yield client.connect_to_host_async(srv_target.get_hostname(), srv_target.get_port()); } catch (Error e) { return null; diff --git a/xmpp-vala/src/module/xep/0368_srv_records_tls.vala b/xmpp-vala/src/module/xep/0368_srv_records_tls.vala index a40d0bb5..3d0708fb 100644 --- a/xmpp-vala/src/module/xep/0368_srv_records_tls.vala +++ b/xmpp-vala/src/module/xep/0368_srv_records_tls.vala @@ -36,6 +36,7 @@ public class TlsConnectionProvider : ConnectionProvider { public async override IOStream? connect(XmppStream stream) { SocketClient client = new SocketClient(); try { + debug("Connecting to %s %i (tls)", srv_target.get_hostname(), srv_target.get_port()); IOStream? io_stream = yield client.connect_to_host_async(srv_target.get_hostname(), srv_target.get_port()); TlsConnection tls_connection = TlsClientConnection.new(io_stream, new NetworkAddress(stream.remote_name.to_string(), srv_target.get_port())); tls_connection.accept_certificate.connect(stream.get_module(Tls.Module.IDENTITY).on_invalid_certificate); |