From 6bb985f9c4bdb4b6a1ba9ef7337c13fb065f6ea7 Mon Sep 17 00:00:00 2001 From: MarekWo Date: Sun, 1 Mar 2026 21:46:08 +0100 Subject: [PATCH] fix(contacts): respect manual approval + fix message delay 1. Manual approval: _on_new_contact now checks self_info manual_add_contacts flag. When enabled, new contacts stay in mc.pending_contacts for UI approval instead of auto-adding to DB. 2. Message delay: disable auto_update_contacts which was triggering full contact list refresh (270+ records over serial) on every ADVERTISEMENT event, blocking message reception for seconds. Contact names for adverts are looked up from cached mc.contacts. Co-Authored-By: Claude Opus 4.6 --- app/device_manager.py | 61 +++++++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/app/device_manager.py b/app/device_manager.py index b5302ec..4563566 100644 --- a/app/device_manager.py +++ b/app/device_manager.py @@ -169,8 +169,11 @@ class DeviceManager: # Subscribe to events await self._subscribe_events() - # Enable auto-refresh of contacts on adverts/path updates - self.mc.auto_update_contacts = True + # NOTE: Do NOT enable mc.auto_update_contacts — it triggers + # full contact list refresh (270+ records over serial) on every + # ADVERTISEMENT event, blocking message reception for seconds. + # Contact names for adverts are looked up from mc.contacts dict + # which was populated during ensure_contacts() below. # Fetch initial contacts from device await self.mc.ensure_contacts() @@ -472,29 +475,47 @@ class DeviceManager: logger.error(f"Error handling path update: {e}") async def _on_new_contact(self, event): - """Handle new contact discovered.""" + """Handle new contact discovered. + + When manual_add_contacts is enabled on the device, new contacts + stay in mc.pending_contacts for manual approval. We should NOT + auto-add them to our DB contacts table — only log them. + When manual mode is off, the device auto-adds and we upsert to DB. + """ try: data = getattr(event, 'payload', {}) pubkey = data.get('public_key', '') name = data.get('adv_name', data.get('name', '')) - if pubkey: - 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='device', - ) - logger.info(f"New contact: {name} ({pubkey[:8]}...)") + if not pubkey: + return + + # Check if manual approval mode is active + manual_mode = False + if self._self_info: + manual_mode = self._self_info.get('manual_add_contacts', False) + + if manual_mode: + # Don't add to DB — let user approve via pending contacts UI + logger.info(f"New contact (pending): {name} ({pubkey[:8]}...)") + return + + 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='device', + ) + logger.info(f"New contact: {name} ({pubkey[:8]}...)") except Exception as e: logger.error(f"Error handling new contact: {e}")