- 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>
Adds a Quote button next to Reply that allows quoting a message.
- Messages ≤20 bytes are quoted in full
- Longer messages are truncated with "..."
- Format: @[Username] "quoted text"
- Uses UTF-8 byte counting for accurate truncation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The template literal had newlines and spaces that were preserved by
white-space: pre-wrap CSS, causing unwanted gaps before and after
image previews in chat messages.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changed message content container from <p> to <div> to fix invalid HTML
when image previews are embedded. The <p> tag cannot contain block-level
elements like <div>, causing browsers to auto-close the paragraph and
create unwanted spacing between text and image preview.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Rename Settings to Device Info with new cpu icon
- Display device parameters in readable table format
- Add copy-to-clipboard buttons for Name and Public Key
- Add map button for device location coordinates
- Show human-readable parameter names and values
- Hide telemetry parameters (not commonly needed)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Messages are now displayed immediately, then re-rendered once geo cache
is ready so Map buttons appear for contacts with GPS coordinates.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Geo cache now loads fully in background without blocking setupAutoRefresh().
UI is ready as soon as messages are displayed.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add 60s cache for /api/contacts/detailed (reduces 4 USB calls to 0)
- Optimize /api/messages/updates to read file once instead of N×2 times
- Parallelize initialization: timestamps loaded together, messages and
geo cache loaded in parallel
- Defer checkForUpdates() to after messages are displayed
- Remove blocking checkForUpdates() from loadChannels()
- Add cache invalidation for contacts on add/delete operations
- Add performance timing logs to browser console
Expected improvement: ~10-20s → ~2-3s initial load time
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use CircleMarker with different colors per contact type:
- CLI (blue), REP (green), ROOM (purple), SENS (orange)
- Add type filter checkboxes in map modal header
- Dynamically update markers when filters change
- Hide filter panel for single contact view
- Reduce message action buttons to 32x32px
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove text labels from Reply and Map buttons
- Add consistent 36x36px square buttons with icons only
- Add tooltips for accessibility
- Prepare for adding more action buttons in the future
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Leaflet CSS/JS and map modal to contacts_base.html
- Add showContactOnMap function to contacts.js (contacts page has separate template)
- Load contactsGeoCache before messages to ensure Map buttons appear on bubbles
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace Google Maps with Leaflet + OpenStreetMap (free, no API key)
- Add Map button in main menu to show all contacts with GPS
- Add Map button on message bubbles (next to Reply) for senders with GPS
- Contact Management Map buttons now open modal instead of new tab
- Lazy map initialization with proper Bootstrap modal handling
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This variable was defined but never used in the code.
Contact cleanup threshold is controlled directly in the UI.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Most users don't need to edit .env anymore. Serial port and device
name are auto-detected. Troubleshooting section collapsed by default.
Reduced installation from 8 steps to 7.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
ttyACM uses major 166, not 188 like ttyUSB.
Needed for Espressif ESP32-S3 based devices (Heltec V3, etc.)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When MC_SERIAL_PORT=auto, bridge scans /dev/serial/by-id/ and:
- Uses the device if exactly one found
- Fails with helpful message if multiple devices (list provided)
- Fails if no devices found
docker-compose.yml now uses device_cgroup_rules instead of explicit
device mapping, allowing auto-detection inside the container.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Updated README.md and .env.example to recommend auto-detection
of device name from meshcli prompt instead of manual configuration.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Meshcli outputs status lines like "Fetching channels ....DeviceName|*".
Updated detection to extract device name after dot sequences.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Bridge now detects device name from meshcli prompt ("DeviceName|*")
and exposes it via /health endpoint. mc-webui fetches this at startup
and uses RuntimeConfig for dynamic device name throughout the app.
Fallback chain: prompt detection → .infos command → MC_DEVICE_NAME env var
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The filteredCountBadge in "Add Filtered" button was not updating when
unchecking type filter checkboxes resulted in zero matching contacts.
Now resets badge to '0' and clears filteredPendingContacts array.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
gevent async_mode requires monkey-patching at startup and was causing
6-12s page load times (vs 1-2s before). Threading mode doesn't require
special setup and is sufficient for occasional Console commands.
- Change async_mode from 'gevent' to 'threading'
- Remove gevent/gevent-websocket from requirements (bridge has its own)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Flask-SocketIO to Tech Stack
- Add WebSocket support to mc-webui container description
- Add console.js and socket.io to Project Structure
- Add console.html to templates list
- Add WebSocket API section with Console events and features
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Console to Key Features list
- Add Console to Basic Usage section
- Add Console to Completed Features checklist
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Previous fix with TERM=dumb caused Public channel to disappear.
Only setting COLUMNS and LINES as fallback for os.get_terminal_size().
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
meshcli calls os.get_terminal_size() which fails without a TTY.
Setting COLUMNS, LINES, and TERM=dumb provides fallback values.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Previous regex was too specific with \[\d+\] pattern.
New pattern ^[^|]+\|\* matches any line starting with <name>|*
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Background tasks lose socket context, so emit() doesn't work.
Fixed by capturing socket ID and using socketio.emit(room=sid).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Browser blocks mixed content (HTTPS page -> HTTP WebSocket on port 5001).
Solution: Route WebSocket through main Flask app which goes through
existing HTTPS reverse proxy.
- Add Flask-SocketIO to main mc-webui app
- WebSocket handler proxies commands to bridge via HTTP
- Remove port 5001 external exposure (no longer needed)
- Remove duplicate title from console header
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Flask-SocketIO backend with gevent for real-time communication
- Create chat-style console UI showing only user's command responses
- WebSocket commands tracked separately from HTTP API (ws_ prefix)
- Console accessible from main menu as fullscreen modal
- Command history navigation with arrow keys
- Auto-reconnection on disconnect
- Update service worker cache for offline support
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Changed hard limit from 8 to 40 channels (most LoRa devices support up to 40)
- Added soft warning when exceeding 7 channels (some devices may have lower limits)
- Warning displayed in UI after successful channel creation/join
- Updated error message to reflect new 40-channel maximum
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Simplify README.md from ~925 to ~217 lines
- Create docs/user-guide.md with detailed feature documentation
- Create docs/architecture.md with technical details and API reference
- Create docs/troubleshooting.md (merged from COMMON_ISSUES.md + README)
- Move DOCKER_INSTALL.md to docs/docker-install.md
- Remove COMMON_ISSUES.md (content merged into troubleshooting.md)
- Add Documentation section with links to all docs
The README now focuses on quick start and installation,
while detailed documentation is organized in docs/ folder.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove images/installation guide/ folder and its contents:
- 01-02. Flashing - selecting role.png
- 01-03. Flashing - connecting to device.png
- 01-04. Flashing - flashing process.png
- 01. Flashing.png
- manual approval.png
These screenshots were originally planned for the installation guide
but are no longer needed.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>