diff options
Diffstat (limited to 'libdino')
| -rw-r--r-- | libdino/src/application.vala | 2 | ||||
| -rw-r--r-- | libdino/src/entity/settings.vala | 13 | ||||
| -rw-r--r-- | libdino/src/service/entity_info.vala | 63 | ||||
| -rw-r--r-- | libdino/src/service/module_manager.vala | 1 |
4 files changed, 74 insertions, 5 deletions
diff --git a/libdino/src/application.vala b/libdino/src/application.vala index 737c76c2..ef2d883e 100644 --- a/libdino/src/application.vala +++ b/libdino/src/application.vala @@ -52,7 +52,7 @@ public interface Application : GLib.Application { NotificationEvents.start(stream_interactor); SearchProcessor.start(stream_interactor, db); Register.start(stream_interactor, db); - EntityInfo.start(stream_interactor, db); + EntityInfo.start(stream_interactor, db, settings); MessageCorrection.start(stream_interactor, db); FileTransferStorage.start(stream_interactor, db); Reactions.start(stream_interactor, db); diff --git a/libdino/src/entity/settings.vala b/libdino/src/entity/settings.vala index 14ac106e..c71a8e57 100644 --- a/libdino/src/entity/settings.vala +++ b/libdino/src/entity/settings.vala @@ -9,6 +9,7 @@ public class Settings : Object { send_typing_ = col_to_bool_or_default("send_typing", true); send_marker_ = col_to_bool_or_default("send_marker", true); + share_time_ = col_to_bool_or_default("share_time", true); notifications_ = col_to_bool_or_default("notifications", true); convert_utf8_smileys_ = col_to_bool_or_default("convert_utf8_smileys", true); check_spelling = col_to_bool_or_default("check_spelling", true); @@ -43,6 +44,18 @@ public class Settings : Object { } } + private bool share_time_; + public bool share_time { + get { return share_time_; } + set { + db.settings.upsert() + .value(db.settings.key, "share_time", true) + .value(db.settings.value, value.to_string()) + .perform(); + share_time_ = value; + } + } + private bool notifications_; public bool notifications { get { return notifications_; } diff --git a/libdino/src/service/entity_info.vala b/libdino/src/service/entity_info.vala index 83e27d4b..53d14b15 100644 --- a/libdino/src/service/entity_info.vala +++ b/libdino/src/service/entity_info.vala @@ -13,23 +13,35 @@ public class EntityInfo : StreamInteractionModule, Object { private StreamInteractor stream_interactor; private Database db; private EntityCapabilitiesStorage entity_capabilities_storage; - + private Dino.Entities.Settings settings; private HashMap<Jid, string> entity_caps_hashes = new HashMap<Jid, string>(Jid.hash_func, Jid.equals_func); private HashMap<string, Gee.List<string>> entity_features = new HashMap<string, Gee.List<string>>(); private HashMap<Jid, Gee.List<string>> jid_features = new HashMap<Jid, Gee.List<string>>(Jid.hash_func, Jid.equals_func); private HashMap<string, Gee.Set<Identity>> entity_identity = new HashMap<string, Gee.Set<Identity>>(); private HashMap<Jid, Gee.Set<Identity>> jid_identity = new HashMap<Jid, Gee.Set<Identity>>(Jid.hash_func, Jid.equals_func); + private HashMap<Jid, int> jid_utc_offset_minutes = new HashMap<Jid, int>(Jid.hash_func, Jid.equals_func); + private HashMap<Jid, int> jid_utc_offset_cache_timeout = new HashMap<Jid, int>(Jid.hash_func, Jid.equals_func); - public static void start(StreamInteractor stream_interactor, Database db) { - EntityInfo m = new EntityInfo(stream_interactor, db); + public static void start(StreamInteractor stream_interactor, Database db, Dino.Entities.Settings settings) { + EntityInfo m = new EntityInfo(stream_interactor, db, settings); stream_interactor.add_module(m); + WeakRef m_weak = WeakRef(m); + ulong handler_id = settings.notify["share-time"].connect(() => { + EntityInfo? entity_info = m_weak.get() as EntityInfo; + if (entity_info != null) { + entity_info.jid_utc_offset_minutes.clear(); + entity_info.jid_utc_offset_cache_timeout.clear(); + } + }); + m.weak_ref(() => settings.disconnect(handler_id)); } - private EntityInfo(StreamInteractor stream_interactor, Database db) { + private EntityInfo(StreamInteractor stream_interactor, Database db, Dino.Entities.Settings settings) { this.stream_interactor = stream_interactor; this.db = db; this.entity_capabilities_storage = new EntityCapabilitiesStorage(db); + this.settings = settings; stream_interactor.account_added.connect(on_account_added); stream_interactor.connection_manager.stream_opened.connect((account, stream) => { @@ -78,6 +90,45 @@ public class EntityInfo : StreamInteractionModule, Object { return null; } + public async int get_utc_offset_minutes_for_full_jid(Account account, Jid full_jid) { + if (!settings.share_time) return int.MIN; + if (!yield has_feature(account, full_jid, EntityTime.NS_URI)) return int.MIN; + int monotonic_time_minutes = (int) (get_monotonic_time() / 1000000l); + if (jid_utc_offset_minutes.has_key(full_jid)) { + if (jid_utc_offset_cache_timeout[full_jid] > monotonic_time_minutes) { + return jid_utc_offset_minutes.get(full_jid); + } else { + jid_utc_offset_minutes.unset(full_jid); + jid_utc_offset_cache_timeout.unset(full_jid); + } + } + XmppStream? stream = stream_interactor.get_stream(account); + if (stream == null) return int.MIN; + DateTime? time = yield stream.get_module(EntityTime.Module.IDENTITY).query_time(stream, full_jid); + int utc_offset = time == null ? int.MIN : (int) (time.get_utc_offset() / TimeSpan.MINUTE); + jid_utc_offset_minutes.set(full_jid, utc_offset); + jid_utc_offset_cache_timeout.set(full_jid, monotonic_time_minutes + 3 * 60 * 60); + return utc_offset; + } + + public async int get_utc_offset_minutes_for_bare_jid(Account account, Jid bare_jid) { + if (stream_interactor.get_module(RosterManager.IDENTITY).get_roster_item(account, bare_jid) == null) return int.MIN; + int utc_offset_minutes = int.MIN; + Gee.List<Jid>? full_jids = stream_interactor.get_module(PresenceManager.IDENTITY).get_full_jids(bare_jid, account); + if (full_jids != null) { + foreach (Jid full_jid in full_jids) { + int jid_utc_offset_minutes = yield get_utc_offset_minutes_for_full_jid(account, full_jid); + if (utc_offset_minutes == int.MIN) { + utc_offset_minutes = jid_utc_offset_minutes; + } else if (jid_utc_offset_minutes != int.MIN && utc_offset_minutes != jid_utc_offset_minutes) { + // Return early, time zones don't match + return int.MIN; + } + } + } + return utc_offset_minutes; + } + public async bool has_feature(Account account, Jid jid, string feature) { int has_feature_cached = has_feature_cached_int(account, jid, feature); if (has_feature_cached != -1) { @@ -248,6 +299,10 @@ public class EntityInfo : StreamInteractionModule, Object { private void initialize_modules(Account account, ArrayList<XmppStreamModule> modules) { modules.add(new Xep.EntityCapabilities.Module(entity_capabilities_storage)); + var entity_time_module = modules.first_match((it) => it is EntityTime.Module) as EntityTime.Module; + if (entity_time_module != null) { + settings.bind_property("share-time", entity_time_module, "enabled", BindingFlags.SYNC_CREATE); + } } } diff --git a/libdino/src/service/module_manager.vala b/libdino/src/service/module_manager.vala index ef6ecc00..64be76e1 100644 --- a/libdino/src/service/module_manager.vala +++ b/libdino/src/service/module_manager.vala @@ -67,6 +67,7 @@ public class ModuleManager { module_map[account].add(new Xep.ChatStateNotifications.Module()); module_map[account].add(new Xep.ChatMarkers.Module()); module_map[account].add(new Xep.Ping.Module()); + module_map[account].add(new Xep.EntityTime.Module()); module_map[account].add(new Xep.DelayedDelivery.Module()); module_map[account].add(new StreamError.Module()); module_map[account].add(new Xep.InBandRegistration.Module()); |
