aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libdino/src/application.vala4
-rw-r--r--libdino/src/entity/conversation.vala2
-rw-r--r--libdino/src/service/avatar_manager.vala35
-rw-r--r--libdino/src/service/conversation_manager.vala57
-rw-r--r--libdino/src/service/registration.vala25
-rw-r--r--main/data/conversation_summary/view.ui3
-rw-r--r--main/data/theme.css4
-rw-r--r--main/src/ui/avatar_image.vala4
-rw-r--r--main/src/ui/conversation_selector/conversation_selector.vala2
-rw-r--r--main/src/ui/conversation_summary/content_item_widget_factory.vala1
-rw-r--r--main/src/ui/conversation_summary/conversation_item_skeleton.vala79
-rw-r--r--main/src/ui/conversation_summary/conversation_view.vala111
-rw-r--r--xmpp-vala/src/core/xmpp_log.vala4
-rw-r--r--xmpp-vala/src/core/xmpp_stream.vala5
-rw-r--r--xmpp-vala/src/module/xep/0368_srv_records_tls.vala1
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);