generated from exteraGramPlugins/pluginBase
Message Logger: keep own deletions, remove from view, reset marks
Publish plugin / publish (push) Successful in 4s
Publish plugin / publish (push) Successful in 4s
- Delete dialog: "Keep message for myself" checkbox keeps your deletion on this device (marked deleted); unticked, the message is hidden and never restored. Already deleted messages get a plain "Remove from view" dialog (fixes the chat staying dimmed/touch-blocked after it). - "Reset deleted/edited marks" in the chat menu (Plugins) and, for all chats, in the plugin settings. - Fix restored text-only messages showing as empty bubbles (rich text wrappers like links lost their text); missing settings icons. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
bbe4a557a8
commit
0176f7099d
9 files changed
+586
-12
No files matched your search
@@ -91,6 +91,11 @@ def _conn():
|
||||
"at REAL, PRIMARY KEY (account, dialog_id, message_id))"
|
||||
)
|
||||
_db.execute("CREATE TABLE IF NOT EXISTS meta (key TEXT PRIMARY KEY, value TEXT)")
|
||||
_db.execute(
|
||||
"CREATE TABLE IF NOT EXISTS hidden ("
|
||||
"account INTEGER, dialog_id INTEGER, message_id INTEGER, at REAL, "
|
||||
"PRIMARY KEY (account, dialog_id, message_id))"
|
||||
)
|
||||
_db.execute(
|
||||
"CREATE TABLE IF NOT EXISTS coverage ("
|
||||
"account INTEGER, dialog_id INTEGER, low INTEGER, high INTEGER, at REAL, "
|
||||
@@ -180,10 +185,12 @@ def cached_deleted(account, dialog_id, low, high):
|
||||
[low, high] (what a restore needs, without asking the server again)."""
|
||||
with _lock:
|
||||
_local_ids(account, dialog_id)
|
||||
hidden = _hidden_ids(account, dialog_id)
|
||||
return [
|
||||
state.raw
|
||||
for message_id, state in _states.get((account, dialog_id), {}).items()
|
||||
if low <= message_id <= high
|
||||
and message_id not in hidden
|
||||
and state.raw is not None
|
||||
and state.raw.get("deleted_at")
|
||||
and state.raw.get("logged")
|
||||
@@ -284,6 +291,79 @@ def forget_deleted(account, dialog_id, message_ids):
|
||||
diag.error("store.forget_deleted", exc)
|
||||
|
||||
|
||||
def reset(account=None, dialog_id=None):
|
||||
"""Forgets cached marks, local deletion records and checked ranges of a
|
||||
chat (or of every chat when `dialog_id` is None); the next look asks the
|
||||
server again. Messages the user removed from view stay hidden.
|
||||
Returns the number of marks forgotten."""
|
||||
where, args = "", ()
|
||||
if dialog_id is not None:
|
||||
where, args = " WHERE account=? AND dialog_id=?", (int(account), int(dialog_id))
|
||||
with _lock:
|
||||
removed = 0
|
||||
try:
|
||||
db = _conn()
|
||||
for table in ("states", "deleted", "coverage"):
|
||||
count = db.execute(f"DELETE FROM {table}{where}", args).rowcount
|
||||
if table != "coverage":
|
||||
removed += count
|
||||
db.commit()
|
||||
except Exception as exc:
|
||||
diag.error("store.reset", exc)
|
||||
if dialog_id is None:
|
||||
_states.clear()
|
||||
_local.clear()
|
||||
_coverage.clear()
|
||||
_loaded.clear()
|
||||
else:
|
||||
key = (int(account), int(dialog_id))
|
||||
for cache in (_states, _local, _coverage):
|
||||
cache.pop(key, None)
|
||||
_loaded.discard(key)
|
||||
return removed
|
||||
|
||||
|
||||
_hidden = {} # (account, dialog_id) -> set of ids the user removed from view
|
||||
|
||||
|
||||
def _hidden_ids(account, dialog_id):
|
||||
key = (account, dialog_id)
|
||||
if key not in _hidden:
|
||||
found = set()
|
||||
try:
|
||||
rows = _conn().execute(
|
||||
"SELECT message_id FROM hidden WHERE account=? AND dialog_id=?", key
|
||||
).fetchall()
|
||||
found = {r[0] for r in rows}
|
||||
except Exception as exc:
|
||||
diag.error("store.hidden", exc)
|
||||
_hidden[key] = found
|
||||
return _hidden[key]
|
||||
|
||||
|
||||
def hide(account, dialog_id, message_ids):
|
||||
"""Messages the user deleted (or removed from view): never shown or
|
||||
restored here again."""
|
||||
ids = [int(i) for i in message_ids]
|
||||
with _lock:
|
||||
_hidden_ids(account, dialog_id).update(ids)
|
||||
try:
|
||||
db = _conn()
|
||||
now = time.time()
|
||||
db.executemany(
|
||||
"INSERT OR IGNORE INTO hidden VALUES (?, ?, ?, ?)",
|
||||
[(account, dialog_id, i, now) for i in ids],
|
||||
)
|
||||
db.commit()
|
||||
except Exception as exc:
|
||||
diag.error("store.hide", exc)
|
||||
|
||||
|
||||
def is_hidden(account, dialog_id, message_id):
|
||||
with _lock:
|
||||
return int(message_id) in _hidden_ids(account, dialog_id)
|
||||
|
||||
|
||||
def note_own_deletion(account, message_ids):
|
||||
now = time.monotonic()
|
||||
with _lock:
|
||||
|
||||
Reference in new issue
Block a user