diff options
| author | fiaxh <git@lightrise.org> | 2025-09-17 17:47:36 +0200 |
|---|---|---|
| committer | fiaxh <git@lightrise.org> | 2025-09-17 17:47:36 +0200 |
| commit | d625058d76efc9e344dd5e1239a4b040a7d2519a (patch) | |
| tree | 4b5a6dc6ad05cb96f58014d1f8740f632efa4bdc /libdino/src/service/occupant_id_store.vala | |
| parent | fa678bd2cf60ebdcda652794bfb5e06b7bd7917f (diff) | |
Message correction: Use occupant ids, handle correction-before-message
Diffstat (limited to 'libdino/src/service/occupant_id_store.vala')
| -rw-r--r-- | libdino/src/service/occupant_id_store.vala | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/libdino/src/service/occupant_id_store.vala b/libdino/src/service/occupant_id_store.vala new file mode 100644 index 00000000..662b9cbb --- /dev/null +++ b/libdino/src/service/occupant_id_store.vala @@ -0,0 +1,88 @@ +using Xmpp; +using Gee; +using Qlite; + +using Dino.Entities; + +namespace Dino { + + public class OccupantIdStore : StreamInteractionModule, Object { + public static ModuleIdentity<OccupantIdStore> IDENTITY = new ModuleIdentity<OccupantIdStore>("occupant_id_cache"); + public string id { get { return IDENTITY.id; } } + + private Database db; + + // (Account, MUC JID, occupant id) -> occupant db id + private HashMap<Account, HashMap<Jid, HashMap<string, int>>> occupant_db_ids = new HashMap<Account, HashMap<Jid, HashMap<string, int>>>(Account.hash_func, Account.equals_func); + private HashMap<int, string> occupant_nicks = new HashMap<int, string>(); + + public static void start(StreamInteractor stream_interactor, Database db) { + OccupantIdStore m = new OccupantIdStore(db); + stream_interactor.add_module(m); + } + + private OccupantIdStore(Database db) { + this.db = db; + } + + public int get_occupant_db_id(Account account, string occupant_id, Jid muc_jid) { + if (!occupant_db_ids.has_key(account) || !occupant_db_ids[account].has_key(muc_jid) || !occupant_db_ids[account][muc_jid].has_key(occupant_id)) { + warning("Requested unknown occupant db id"); + return -1; + } + + return occupant_db_ids[account][muc_jid][occupant_id]; + } + + public int cache_occupant_id(Account account, string occupant_id, Jid occupant_jid) { + string last_nick = occupant_jid.resourcepart; + Jid muc_jid = occupant_jid.bare_jid; + + if (occupant_db_ids.has_key(account) && occupant_db_ids[account].has_key(muc_jid) && occupant_db_ids[account][muc_jid].has_key(occupant_id)) { + int occupant_db_id = occupant_db_ids[account][muc_jid][occupant_id]; + if (occupant_nicks[occupant_db_id] == last_nick) { + return occupant_db_id; + } + } + + if (!occupant_db_ids.has_key(account)) occupant_db_ids[account] = new HashMap<Jid, HashMap<string, int>>(Jid.hash_bare_func, Jid.equals_bare_func); + if (!occupant_db_ids[account].has_key(muc_jid)) occupant_db_ids[account][muc_jid] = new HashMap<string, int>(); + + int muc_jid_id = db.get_jid_id(muc_jid); + + RowOption row = db.occupantid.select() + .with(db.occupantid.account_id, "=", account.id) + .with(db.occupantid.jid_id, "=", muc_jid_id) + .with(db.occupantid.occupant_id, "=", occupant_id) + .single().row(); + + int occupant_db_id = -1; + if (row.is_present()) { + occupant_db_id = row[db.occupantid.id]; + + if (row[db.occupantid.last_nick] != last_nick) { + db.occupantid.upsert() + .value(db.occupantid.account_id, account.id, true) + .value(db.occupantid.jid_id, muc_jid_id, true) + .value(db.occupantid.occupant_id, occupant_id, true) + .value(db.occupantid.last_nick, last_nick, false) + .perform(); + } + } else { + occupant_db_id = (int)db.occupantid.upsert() + .value(db.occupantid.account_id, account.id, true) + .value(db.occupantid.jid_id, muc_jid_id, true) + .value(db.occupantid.occupant_id, occupant_id, true) + .value(db.occupantid.last_nick, muc_jid.resourcepart, false) + .perform(); + } + + occupant_db_ids[account][muc_jid][occupant_id] = occupant_db_id; + occupant_nicks[occupant_db_id] = last_nick; + + return occupant_db_id; + } + + + } +}
\ No newline at end of file |
