diff options
Diffstat (limited to 'libdino/src')
-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 |
5 files changed, 81 insertions, 42 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); |