This commit is contained in:
pe1hvh
2026-03-12 21:30:44 +01:00
parent a8e148f1a6
commit 3e7b44f8ad
2 changed files with 75 additions and 71 deletions

View File

@@ -77,6 +77,16 @@ class EventHandler:
names.append(h.upper())
return names
@staticmethod
def _looks_like_hex_identifier(value: str) -> bool:
"""Return True when *value* looks like a pubkey/hash prefix."""
if not value:
return False
probe = str(value).strip()
if len(probe) < 6:
return False
return all(ch in '0123456789abcdefABCDEF' for ch in probe)
# ------------------------------------------------------------------
# RX_LOG_DATA — the single source of truth for path info
# ------------------------------------------------------------------
@@ -339,22 +349,33 @@ class EventHandler:
is_room_message = txt_type == 2
if is_room_message:
author = ''
explicit_name = (
payload.get('author')
or payload.get('sender_name')
or payload.get('name')
or ''
)
if explicit_name and not self._looks_like_hex_identifier(explicit_name):
author = explicit_name
sender_field = str(payload.get('sender') or '').strip()
if not author and sender_field and not self._looks_like_hex_identifier(sender_field):
author = sender_field
author_key = (
signature
or payload.get('sender_pubkey')
or payload.get('sender')
or payload.get('author_pubkey')
or (sender_field if self._looks_like_hex_identifier(sender_field) else '')
or ''
)
author = ''
if author_key:
if not author and author_key:
author = self._shared.get_contact_name_by_prefix(author_key)
if not author:
author = (
payload.get('author')
or payload.get('name')
or payload.get('sender_name')
or payload.get('sender')
explicit_name
or sender_field
or (author_key[:8] if author_key else '')
or '?'
)

View File

@@ -77,12 +77,6 @@ class SharedData:
# Room Server login states: pubkey → {'state': 'ok'|'fail'|'pending'|'logged_out', 'detail': str}
self.room_login_states: Dict[str, Dict] = {}
# Known room pubkeys/prefixes (normalised to 12 hex chars).
# This is a central, UI-independent registry used by the
# MessagesPanel to keep Room Server traffic out of All Messages,
# even when the room cards are not yet fully restored.
self._known_room_pubkeys: set[str] = set()
# Room message cache: pubkey_prefix (12 hex) → List[Message]
# Populated from archive on first access per room, then kept in
# sync by add_message().
@@ -183,37 +177,9 @@ class SharedData:
return self.device.name
# ------------------------------------------------------------------
# Room Server login state / known room registry
# Room Server login state
# ------------------------------------------------------------------
@staticmethod
def _normalise_room_pubkey(pubkey: str) -> str:
"""Return a comparable room pubkey prefix.
Normalises a full Room Server pubkey or a shorter prefix to the
canonical 12-hex representation used throughout the room-cache
logic. Returns an empty string for falsey input.
"""
return (pubkey or '').strip()[:12]
def register_room_pubkey(self, pubkey: str) -> None:
"""Register a Room Server pubkey/prefix as known.
Keeps the registry small and stable by storing only the
canonical 12-hex prefix. Safe to call repeatedly.
"""
norm = self._normalise_room_pubkey(pubkey)
if not norm:
return
with self.lock:
self._known_room_pubkeys.add(norm)
def get_known_room_pubkeys(self) -> set[str]:
"""Return a copy of all centrally known Room Server keys."""
with self.lock:
return set(self._known_room_pubkeys)
def set_room_login_state(
self, pubkey_prefix: str, state: str, detail: str = "",
) -> None:
@@ -229,14 +195,9 @@ class SharedData:
state: One of 'pending', 'ok', 'fail', 'logged_out'.
detail: Human-readable detail string.
"""
norm = self._normalise_room_pubkey(pubkey_prefix)
if not norm:
return
with self.lock:
self._known_room_pubkeys.add(norm)
# Remove overlapping entries (different key length, same room)
norm = pubkey_prefix[:12]
stale = [
k for k in self.room_login_states
if k != pubkey_prefix and k[:12] == norm
@@ -279,14 +240,10 @@ class SharedData:
if not self.archive:
return
norm = self._normalise_room_pubkey(pubkey)
if not norm:
return
norm = pubkey[:12]
archived = self.archive.get_messages_by_sender_pubkey(norm, limit)
with self.lock:
self._known_room_pubkeys.add(norm)
messages = [Message.from_dict(d) for d in archived]
self._room_msg_cache[norm] = messages
debug_print(
@@ -302,9 +259,7 @@ class SharedData:
Returns:
List of Message objects (oldest first), or empty list.
"""
norm = self._normalise_room_pubkey(pubkey)
if not norm:
return []
norm = pubkey[:12]
with self.lock:
return list(self._room_msg_cache.get(norm, []))
@@ -604,8 +559,6 @@ class SharedData:
k: v.copy()
for k, v in self.room_login_states.items()
},
# Centrally known room keys (UI-independent)
'known_room_pubkeys': set(self._known_room_pubkeys),
# Room message cache (archived + live)
'room_messages': {
k: list(v)
@@ -640,28 +593,58 @@ class SharedData:
return None
def get_contact_name_by_prefix(self, pubkey_prefix: str) -> str:
"""Resolve a pubkey/prefix to a display name.
"""Resolve a pubkey/prefix to the best available display name.
Accepts either a short prefix or a longer/full public key and
returns the best-known human-readable name. This keeps room
messages readable when the room server reports the author as a
full hash instead of the shorter contact key used elsewhere.
The room server may report the author using different key fields:
a short prefix, a full public key, or a value copied into another
payload field. To keep sender display stable, match against both
the contact dict key and common pubkey-like fields stored inside
each contact record.
"""
if not pubkey_prefix:
return ""
probe = pubkey_prefix.lower()
probe = str(pubkey_prefix).strip().lower()
if not probe:
return ""
def _candidate_keys(contact_key: str, contact: Dict) -> List[str]:
values = [contact_key]
for field in (
'public_key',
'pubkey',
'pub_key',
'publicKey',
'sender_pubkey',
'author_pubkey',
'receiver_pubkey',
'pubkey_prefix',
'signature',
):
value = contact.get(field)
if isinstance(value, str) and value.strip():
values.append(value.strip())
return values
with self.lock:
device_key = (self.device.public_key or '').lower()
if device_key and (device_key.startswith(probe) or probe.startswith(device_key)):
device_key = (self.device.public_key or '').strip().lower()
if device_key and (
device_key.startswith(probe)
or probe.startswith(device_key)
):
return self.device.name or 'Me'
for key, contact in self.contacts.items():
key_lower = key.lower()
if key_lower.startswith(probe) or probe.startswith(key_lower):
name = contact.get('adv_name', '')
if name:
return name
for candidate in _candidate_keys(key, contact):
candidate_lower = candidate.lower()
if (
candidate_lower.startswith(probe)
or probe.startswith(candidate_lower)
):
name = str(contact.get('adv_name', '') or '').strip()
if name:
return name
return pubkey_prefix[:8]
def get_contact_by_name(self, name: str) -> Optional[Tuple[str, Dict]]: