diff --git a/README.md b/README.md index 65f5bed..c7ba70f 100644 --- a/README.md +++ b/README.md @@ -266,22 +266,18 @@ Access the Direct Messages feature: 2. Select "Direct Messages" from the menu 3. Opens a dedicated full-page DM view -**From channel messages:** -- Click the "DM" button next to any message to start a private chat with that user -- You'll be redirected to the DM page with that conversation selected - **Using the DM page:** 1. **Select a recipient** from the dropdown at the top: - **Existing conversations** are shown first (with message history) - Separator: "--- Available contacts ---" - - **All contacts from your device** (meshcli: `contacts`) appear below + - **All client contacts** from your device (only CLI type, no repeaters/rooms) - You can start a new conversation with anyone in your contacts list 2. Type your message in the input field (max 140 bytes, same as channels) 3. Use the emoji picker button to insert emojis 4. Press Enter or click Send 5. Click "Back" button to return to the main chat view -**Note:** You can only send DMs to users in your contacts list. The dropdown shows all available contacts, making it easy to start new conversations. +**Note:** Only client contacts (CLI) are shown in the dropdown. Repeaters (REP), rooms (ROOM), and sensors (SENS) are automatically filtered out. **Message status indicators:** - ⏳ **Pending** (clock icon, yellow) - Message sent, awaiting delivery confirmation diff --git a/app/meshcore/cli.py b/app/meshcore/cli.py index ea9a08f..a3f48be 100644 --- a/app/meshcore/cli.py +++ b/app/meshcore/cli.py @@ -121,7 +121,7 @@ def get_contacts() -> Tuple[bool, str]: return success, stdout or stderr -def parse_contacts(output: str) -> List[str]: +def parse_contacts(output: str, filter_types: Optional[List[str]] = None) -> List[str]: """ Parse meshcli contacts output to extract contact names. @@ -133,6 +133,8 @@ def parse_contacts(output: str) -> List[str]: Args: output: Raw output from meshcli contacts command + filter_types: Optional list of contact types to include (e.g., ['CLI']) + If None, all types are included. Returns: List of contact names (unique) @@ -160,8 +162,10 @@ def parse_contacts(output: str) -> List[str]: # Validate that second column looks like a type if contact_type in ['CLI', 'REP', 'ROOM', 'SENS'] and contact_name: - if contact_name not in contacts: - contacts.append(contact_name) + # Apply type filter if specified + if filter_types is None or contact_type in filter_types: + if contact_name not in contacts: + contacts.append(contact_name) return contacts @@ -169,6 +173,7 @@ def parse_contacts(output: str) -> List[str]: def get_contacts_list() -> Tuple[bool, List[str], str]: """ Get parsed list of contact names from the device. + Only returns CLI (client) contacts, excluding REP, ROOM, and SENS. Returns: Tuple of (success, contact_names_list, error_message) @@ -178,7 +183,8 @@ def get_contacts_list() -> Tuple[bool, List[str], str]: if not success: return False, [], output - contacts = parse_contacts(output) + # Filter only CLI (client) contacts - no repeaters, rooms, or sensors + contacts = parse_contacts(output, filter_types=['CLI']) return True, contacts, "" diff --git a/app/static/js/app.js b/app/static/js/app.js index e19280b..925816c 100644 --- a/app/static/js/app.js +++ b/app/static/js/app.js @@ -347,9 +347,6 @@ function createMessageElement(msg) { - ` : ''} `;