mirror of
https://github.com/MarekWo/mc-webui.git
synced 2026-08-07 09:12:57 +02:00
feat(contacts): complete cache functionality, fix display bugs
- _on_new_contact() in manual mode: upsert to DB as cache (source='advert') so contacts appear in @mentions and Cache filter before approval - _on_advertisement(): check mc.pending_contacts for name/metadata fallback - get_pending_contacts(): include last_advert in response - /api/contacts/cached: return numeric last_advert timestamp - contacts.js: fix adv_lat/adv_lon field names (was c.lat/c.lon), use last_advert timestamp instead of last_seen datetime string - upsert_contact: source priority — never downgrade 'device' to 'advert' Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+5
-1
@@ -107,7 +107,11 @@ class Database:
|
||||
adv_lat = COALESCE(excluded.adv_lat, contacts.adv_lat),
|
||||
adv_lon = COALESCE(excluded.adv_lon, contacts.adv_lon),
|
||||
last_seen = datetime('now'),
|
||||
source = excluded.source,
|
||||
source = CASE
|
||||
WHEN excluded.source = 'device' THEN 'device'
|
||||
WHEN contacts.source = 'device' THEN contacts.source
|
||||
ELSE excluded.source
|
||||
END,
|
||||
is_protected = CASE WHEN contacts.is_protected = 1 THEN 1 ELSE excluded.is_protected END,
|
||||
lastmod = datetime('now')""",
|
||||
fields
|
||||
|
||||
+29
-4
@@ -531,8 +531,15 @@ class DeviceManager:
|
||||
contact = (self.mc.contacts or {}).get(pubkey, {})
|
||||
name = contact.get('adv_name', contact.get('name', ''))
|
||||
|
||||
# If contact is unknown or has no name, firmware may have just auto-added it.
|
||||
# Refresh contacts from device to pick up the new entry.
|
||||
# Also check pending contacts (manual approval mode)
|
||||
if not name:
|
||||
pending = (self.mc.pending_contacts or {}).get(pubkey, {})
|
||||
if pending:
|
||||
name = pending.get('adv_name', pending.get('name', ''))
|
||||
if not contact:
|
||||
contact = pending
|
||||
|
||||
# If contact is still unknown, firmware may have just auto-added it.
|
||||
if not name and pubkey not in (self.mc.contacts or {}):
|
||||
logger.info(f"Unknown advert from {pubkey[:8]}..., refreshing contacts")
|
||||
await self.mc.ensure_contacts(follow=True)
|
||||
@@ -749,9 +756,26 @@ class DeviceManager:
|
||||
return
|
||||
|
||||
if self._is_manual_approval_enabled():
|
||||
# Manual mode: don't add to DB, just notify frontend
|
||||
# meshcore library already puts it in mc.pending_contacts
|
||||
# Manual mode: meshcore puts it in mc.pending_contacts for approval
|
||||
logger.info(f"Pending contact (manual mode): {name} ({pubkey[:8]}...)")
|
||||
|
||||
# Also add to DB cache for @mentions and Cache filter
|
||||
last_adv = data.get('last_advert')
|
||||
last_advert_val = (
|
||||
str(int(last_adv))
|
||||
if last_adv and isinstance(last_adv, (int, float)) and last_adv > 0
|
||||
else str(int(time.time()))
|
||||
)
|
||||
self.db.upsert_contact(
|
||||
public_key=pubkey,
|
||||
name=name,
|
||||
type=data.get('type', data.get('adv_type', 0)),
|
||||
adv_lat=data.get('adv_lat'),
|
||||
adv_lon=data.get('adv_lon'),
|
||||
last_advert=last_advert_val,
|
||||
source='advert', # cache-only until approved
|
||||
)
|
||||
|
||||
if self.socketio:
|
||||
self.socketio.emit('pending_contact', {
|
||||
'public_key': pubkey,
|
||||
@@ -1158,6 +1182,7 @@ class DeviceManager:
|
||||
'type': c.get('type', c.get('adv_type', 0)),
|
||||
'adv_lat': c.get('adv_lat'),
|
||||
'adv_lon': c.get('adv_lon'),
|
||||
'last_advert': c.get('last_advert'),
|
||||
}
|
||||
for pk, c in pending.items()
|
||||
]
|
||||
|
||||
@@ -675,12 +675,20 @@ def get_cached_contacts():
|
||||
contacts = []
|
||||
for c in db_contacts:
|
||||
pk = c.get('public_key', '')
|
||||
# Parse last_advert to numeric timestamp
|
||||
la = c.get('last_advert')
|
||||
try:
|
||||
last_advert_ts = int(la) if la else 0
|
||||
except (ValueError, TypeError):
|
||||
last_advert_ts = 0
|
||||
|
||||
contacts.append({
|
||||
'public_key': pk,
|
||||
'public_key_prefix': pk[:12],
|
||||
'name': c.get('name', ''),
|
||||
'first_seen': c.get('first_seen', ''),
|
||||
'last_seen': c.get('last_seen', ''),
|
||||
'last_advert': last_advert_ts,
|
||||
'source': c.get('source', ''),
|
||||
'adv_lat': c.get('adv_lat'),
|
||||
'adv_lon': c.get('adv_lon'),
|
||||
|
||||
@@ -1652,9 +1652,9 @@ async function loadExistingContacts() {
|
||||
public_key: c.public_key,
|
||||
public_key_prefix: c.public_key_prefix || c.public_key.substring(0, 12),
|
||||
type_label: c.type_label || '',
|
||||
adv_lat: c.lat || 0,
|
||||
adv_lon: c.lon || 0,
|
||||
last_seen: c.last_seen || 0,
|
||||
adv_lat: c.adv_lat || 0,
|
||||
adv_lon: c.adv_lon || 0,
|
||||
last_seen: c.last_advert || 0,
|
||||
on_device: false,
|
||||
source: c.source || 'cache'
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user