Remove nested @media (max-width: 400px) rule that forced btn-group
to flex-direction: column, causing buttons to stack on mobile.
Also remove now-unused .list-group-item small styles (channel keys
no longer shown).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add confirm() dialog before marking all messages as read, showing
list of unread channels with counts. Remove channel key/ID from
Manage Channels modal to save vertical space on mobile.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add ability to mute notifications for individual channels via Manage
Channels modal (bell/bell-slash toggle button). Muted channels are
excluded from unread badge counts, browser notifications, and app icon
badge. Bell icon click now marks all channels as read in bulk.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add person icon button in filter bar that inserts the current device
name into the search field, for filtering own messages
- DM filter bar already benefits from the CSS sibling push-down rule
added in previous commit (same class names used)
- Add collapsible FAB toggle to DM view, same pattern as channel chat
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add collapsible FAB container with chevron toggle button to
temporarily hide floating action buttons that overlap messages
- Make filter bar push messages down instead of overlaying the first
matched message (CSS sibling selector adds padding-top)
- Add @mentions autocomplete to filter search bar - typing @ shows
contact list dropdown, selecting inserts plain name (not @[] format)
so all messages from/mentioning that user are found
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Extract lat/lon from advert payloads (struct unpack from binary)
- Store type_label and lat/lon in cache from device seed and adverts
- Show Map button for cache contacts with GPS coordinates
- Show colored type badge (CLI/REP/ROOM/SENS) for typed cache contacts
- Type filter now works for cache contacts with known type
- Change counter label from "known" to "cached"
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replaces two sort toggle buttons with a single <select> dropdown (e-commerce style)
so all 3 filter/sort controls fit on mobile screens.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Contacts cache accumulates all known node names from device contacts
and adverts into a JSONL file, so @mentions work even after contacts
are removed from the device. Background thread scans adverts every
45s and parses advert payloads to extract public keys and node names.
Existing Contacts page now shows merged view with "Cache" badge for
contacts not on device, plus source filter (All/On device/Cache only).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
bi-flask was added in Bootstrap Icons 1.12+, but project uses 1.11.2.
Replace with bi-clipboard-data which is available and conveys
"data analysis".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Generate analyzer_url from computed pkt_payload for all incoming
channel messages, not just those with echo path matches. This means
the analyzer button appears even when no route paths were captured.
Also change analyzer button icon from bi-search (magnifying glass)
to bi-flask (lab flask) to better convey "analysis/inspection".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace unreliable timestamp-based heuristic (±10s window) with exact
cryptographic matching for incoming channel message routes. Compute
pkt_payload by reconstructing the AES-128-ECB encrypted packet from
message data (sender_timestamp, txt_type, text) + channel secret, then
match against echo data by exact key lookup.
Also accumulate ALL route paths per message (previously only last path
was kept due to dict overwrite), and display them in a multi-path popup
showing SNR and hops for each route.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add clickable "?" icon on DMs without ACK, showing a popup
explaining that delivery is unknown (mobile-friendly).
Update README, user guide with new features (Analyzer links,
DM delivery tracking).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Stop scheduling further post-send reloads as soon as the last
own message shows a delivery checkmark.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add two extra delayed reloads (6s, 15s) after sending a DM,
matching the channel chat pattern, so ACK checkmarks appear
without needing to send another message.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Bridge captures ACK packets from meshcli stdout (json_log_rx),
persists to .acks.jsonl, and exposes /ack_status endpoint.
Delivery status is merged server-side into DM messages and
displayed as a green checkmark with SNR/route tooltip.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Compute packet_hash from pkt_payload (SHA-256 of type byte + payload)
and generate analyzer.letsmesh.net links. Button appears on both sent
and received messages when echo data is available.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tooltips don't work on touchscreens. Added a popup that appears on
tap/click, shows the full path, and auto-dismisses after 4 seconds.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Deduplicate 2-char repeater codes in echo badge (same repeater via
different routes was shown twice, e.g., "3 (d1, 5e, 5e)")
- Use deduplicated count for unique repeaters, not unique full paths
- Improve incoming path correlation: widen window to 10s, prefer
path_len match but fall back to timestamp-only if needed
- Add debug logging for incoming path correlation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Show repeater path codes in sent message echo badge (e.g., "2 (5e, d1)")
- Capture and display route path for incoming messages in message meta
- Persist all echo data to .echoes.jsonl (survives container restarts)
- Load echo data from disk on startup with 7-day retention and compaction
- Combine sent echo and incoming path data in single /echo_counts response
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add sender name above outgoing messages in group chat
- Display emoji-only messages in larger font size
- Fix leading space before text in quoted replies
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Auto-detect #channel names in messages and convert to clickable links
- Click existing channel: switch to it via channel selector
- Click non-existing channel: join via API, then switch
- Green styling to distinguish from blue @mentions
- Only active in channel context (not in DMs)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add filter-utils.js with diacritic-insensitive search and text highlighting
- Add FAB filter button (gray funnel icon) to channel chat and DM
- Filter bar slides in as overlay at top of chat area
- Real-time filtering with debounce (150ms) as user types
- Matched text highlighted with yellow background
- Support for Polish characters (wol matches wół)
- Keyboard shortcuts: Ctrl+F to open, Escape to close
- Match counter shows X / Y filtered messages
- Filter persists during auto-refresh
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Echo counts weren't appearing until sending another message because
auto-refresh only triggers when new messages arrive. Added 6s and 15s
delayed reloads after sending to catch echoes as they arrive.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Track how many repeaters heard and forwarded sent channel messages,
similar to the Meshcore mobile app's "Heard X repeats" feature.
- Bridge: Detect GRP_TXT echoes from stdout, track unique paths
- Bridge: New /register_echo and /echo_counts API endpoints
- API: Register messages for echo tracking after send
- API: Merge echo counts into /api/messages response
- Frontend: Display green badge with broadcast icon next to Resend button
- CSS: Echo badge styling with dark mode support
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add server-side API for console history (GET/POST/DELETE)
- Add history dropdown button with clock icon
- Save commands to server after execution
- Load history from server on page load
- History persists between sessions and works across devices
- Max 50 commands stored, duplicates moved to end
- Dropdown shows most recent commands first
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Semi-transparent button appears when user scrolls up
- Positioned at bottom-right of messages container
- Clicking scrolls to latest messages and hides button
- Smooth fade-in/out animation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Resend button under own messages in channel chat and DM
(allows easy re-sending of failed messages)
- Change channel chat limit from 140 to 135 bytes
- Change DM limit from 140 to 150 bytes
(experimentally verified Meshcore limits)
- Remove misleading Hops info from DM message bubbles
- Update README with new byte limits
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When user types @ in the message input, a dropdown appears with contacts
list. The list filters as user types (matches any part of name, not just
prefix). User can navigate with arrow keys, select with Enter/Tab/click,
or dismiss with Escape.
- Add mentions popup HTML to index.html
- Add mentions CSS styling (responsive, scrollable)
- Add JavaScript logic: detection, filtering, keyboard nav, insertion
- Contacts cached for 60s, loaded on input focus
- Closes emoji picker when mentions opens (avoid overlap)
- Inserts selected contact as @[username] format
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The scheduler now uses the timezone configured in .env (TZ variable)
instead of hardcoded UTC:
- Add get_local_timezone_name() helper to manager.py
- BackgroundScheduler uses system local timezone
- API returns timezone field in cleanup-settings response
- Frontend displays timezone next to hour selector and in status text
- Updated documentation to reflect timezone behavior
This makes the cleanup hour more intuitive for users in non-UTC timezones.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Allow users to select the hour (0-23 UTC) when automatic contact
cleanup runs:
- Add hour selector dropdown in Advanced Filters (disabled until enabled)
- Hour field saved to .webui_settings.json with cleanup_settings
- API validates hour (0-23), scheduler uses CronTrigger with hour param
- Status text shows configured hour (e.g., "Enabled (runs daily at 03:00 UTC)")
- Documentation updated in user-guide.md
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add auto-cleanup feature that runs daily at 01:00 UTC using APScheduler:
- New cleanup settings stored in .webui_settings.json (enabled, types, date_field, days, name_filter)
- API endpoints: GET/POST /api/contacts/cleanup-settings
- Scheduler functions: _cleanup_job(), schedule_cleanup(), init_cleanup_schedule()
- UI toggle in Advanced Filters with validation (requires days > 0)
- Debounced auto-save for filter criteria changes
- Protected contacts are excluded from auto-cleanup
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove separate "Copy Key" button
- Make public key prefix clickable to copy
- Add fallback for HTTP contexts (execCommand)
- Add hover and copied state styling
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add ability to protect contacts from accidental deletion via Contact
Cleanup tool. Protected contacts are stored locally in settings file.
Changes:
- Add GET /api/contacts/protected endpoint
- Add POST /api/contacts/<key>/protect toggle endpoint
- Add is_protected field to /api/contacts/detailed response
- Exclude protected contacts from cleanup preview and deletion
- Add Protect toggle button to Existing Contacts list
- Show lock icon for protected contacts
- Disable Delete button for protected contacts
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Convert type filter checkboxes to clickable toggle badges on the Map
modal (accessible from main menu). Same UX pattern as pending contacts:
- Active: colored background, white text
- Inactive: colored text/border, white background
Updated in both base.html and contacts_base.html for consistency.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace type filter checkboxes with clickable toggle badges in Pending
Contacts (CLI/REP/ROOM/SENS) - more compact and better mobile UX
- Make Pending Contacts buttons (Approve, Map, Copy Key) smaller and
uniform, matching Existing Contacts button style
- Optimize Existing Contacts filter toolbar to fit in one row on mobile
(narrower dropdown, more compact sort buttons)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add sudo to journalctl command in install.sh help text
- Move "Update now" link below version number to prevent line wrap
- Add "What's new?" link in update modal pointing to GitHub commits
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds webhook-based update system that allows triggering updates
directly from the mc-webui menu. Includes:
- Webhook server (updater.py) on port 5050
- Systemd service and install script
- API proxy endpoints for container-to-host communication
- Update modal with progress tracking and auto-reload
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add /api/check-update endpoint that queries GitHub API
- Compare current commit hash with latest on dev branch
- Add check button next to version in menu
- Show spinning icon during check, green checkmark when done
- Display "Update available" link when newer version exists
- Handle rate limits and network errors gracefully
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Reduce emoji avatar border from 2.5px to 1.5px
- Reduce horizontal padding from 0.5rem to 0.25rem
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Emoji avatars are now displayed with a colored ring/outline
instead of filled background for better readability.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Reduce horizontal padding in messages container
- Add colored circle background to emoji avatars
- Fix vertical alignment of avatar with sender name
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add mini avatars next to sender names in channel chat
- Extract emoji from username for avatar (first emoji only)
- Use initials for users without emoji (1-2 letters)
- Generate consistent colors based on username hash
- Move sender name outside message bubble (MeshCore style)
- Add responsive styles for mobile devices
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Format changed from @[User]: »text« to @[User] »text«
Guillemets alone are sufficient to separate the quote.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Guillemets (» «) no longer displayed - styling is sufficient
- Added line break after quoted text for better readability
- Raw message still contains guillemets for compatibility
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Changed quote format to: @[Username]: »quoted text«
- Added processQuotes() to detect and style »text« patterns
- Quote styling: italic, gray background, left border
- Different styling for own messages vs others
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>