aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libdino/src/service/entity_info.vala35
-rw-r--r--libdino/src/service/muc_manager.vala11
-rw-r--r--qlite/src/upsert_builder.vala8
3 files changed, 38 insertions, 16 deletions
diff --git a/libdino/src/service/entity_info.vala b/libdino/src/service/entity_info.vala
index d1217e81..83e27d4b 100644
--- a/libdino/src/service/entity_info.vala
+++ b/libdino/src/service/entity_info.vala
@@ -90,6 +90,20 @@ public class EntityInfo : StreamInteractionModule, Object {
return info_result.features.contains(feature);
}
+ public bool has_feature_offline(Account account, Jid jid, string feature) {
+ int ret = has_feature_cached_int(account, jid, feature);
+ if (ret == -1) {
+ return db.entity.select()
+ .with(db.entity.account_id, "=", account.id)
+ .with(db.entity.jid_id, "=", db.get_jid_id(jid))
+ .with(db.entity.resource, "=", jid.resourcepart ?? "")
+ .join_with(db.entity_feature, db.entity.caps_hash, db.entity_feature.entity)
+ .with(db.entity_feature.feature, "=", feature)
+ .count() > 0;
+ }
+ return ret == 1;
+ }
+
public bool has_feature_cached(Account account, Jid jid, string feature) {
return has_feature_cached_int(account, jid, feature) == 1;
}
@@ -203,13 +217,24 @@ public class EntityInfo : StreamInteractionModule, Object {
ServiceDiscovery.InfoResult? info_result = yield stream.get_module(ServiceDiscovery.Module.IDENTITY).request_info(stream, jid);
if (info_result == null) return null;
- if (hash != null && EntityCapabilities.Module.compute_hash_for_info_result(info_result) == hash) {
- store_features(hash, info_result.features);
- store_identities(hash, info_result.identities);
+ var computed_hash = EntityCapabilities.Module.compute_hash_for_info_result(info_result);
+
+ if (hash == null || computed_hash == hash) {
+ db.entity.upsert()
+ .value(db.entity.account_id, account.id, true)
+ .value(db.entity.jid_id, db.get_jid_id(jid), true)
+ .value(db.entity.resource, jid.resourcepart ?? "", true)
+ .value(db.entity.last_seen, (long)(new DateTime.now_local()).to_unix())
+ .value(db.entity.caps_hash, computed_hash)
+ .perform();
+
+ store_features(computed_hash, info_result.features);
+ store_identities(computed_hash, info_result.identities);
} else {
- jid_features[jid] = info_result.features;
- jid_identity[jid] = info_result.identities;
+ warning("Claimed entity caps hash from %s doesn't match computed one", jid.to_string());
}
+ jid_features[jid] = info_result.features;
+ jid_identity[jid] = info_result.identities;
return info_result;
}
diff --git a/libdino/src/service/muc_manager.vala b/libdino/src/service/muc_manager.vala
index 119079f0..6b52fe36 100644
--- a/libdino/src/service/muc_manager.vala
+++ b/libdino/src/service/muc_manager.vala
@@ -232,15 +232,8 @@ public class MucManager : StreamInteractionModule, Object {
//the term `private room` is a short hand for members-only+non-anonymous rooms
public bool is_private_room(Account account, Jid jid) {
- XmppStream? stream = stream_interactor.get_stream(account);
- if (stream == null) {
- return false;
- }
- Xep.Muc.Flag? flag = stream.get_flag(Xep.Muc.Flag.IDENTITY);
- if (flag == null) {
- return false;
- }
- return flag.has_room_feature(jid, Xep.Muc.Feature.NON_ANONYMOUS) && flag.has_room_feature(jid, Xep.Muc.Feature.MEMBERS_ONLY);
+ var entity_info = stream_interactor.get_module(EntityInfo.IDENTITY);
+ return entity_info.has_feature_offline(account, jid, "muc_membersonly") && entity_info.has_feature_offline(account, jid, "muc_nonanonymous");
}
public bool is_moderated_room(Account account, Jid jid) {
diff --git a/qlite/src/upsert_builder.vala b/qlite/src/upsert_builder.vala
index 7daf7109..79104972 100644
--- a/qlite/src/upsert_builder.vala
+++ b/qlite/src/upsert_builder.vala
@@ -26,9 +26,13 @@ public class UpsertBuilder : StatementBuilder {
return this;
}
- public UpsertBuilder value_null<T>(Column<T> column) {
+ public UpsertBuilder value_null<T>(Column<T> column, bool key = false) {
if (column.not_null) error("Can't set non-null column %s to null", column.name);
- fields += new NullField<T>(column);
+ if (key) {
+ keys += new NullField<T>(column);
+ } else {
+ fields += new NullField<T>(column);
+ }
return this;
}