Commit Graph

22 Commits

Author SHA1 Message Date
MarekWo 75ec789fba feat: Add node discovery feature and improve advert notification
Implemented new "Discover Nodes" feature in Network Commands menu:
- Added .node_discover command to meshcli wrapper (cli.py)
- Created interactive modal with sortable table showing nearby repeaters
- Displays SNR, RSSI, path length, and signal quality indicators
- Added refresh functionality to rescan for nodes

Fixed advert notification to show clean "Advert sent" message
instead of full meshcli output.

Technical changes:
- app/meshcore/cli.py: Added node_discover() function with JSON parsing
- app/routes/api.py: Updated SPECIAL_COMMANDS and execute_special_command()
  to handle node_discover return type and clean advert message
- app/templates/base.html: Added "Discover Nodes" menu button and modal
- app/static/js/app.js: Added discoverNodes() and displayNodeDiscoveryResults()
- README.md: Added documentation for Discover Nodes feature

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-02 14:34:02 +01:00
MarekWo 797096b551 fix: Improve viewport fix to avoid interfering with page initialization
Changed viewport fix approach to be less invasive:
- Removed document.body.style.height modification
- Use document.documentElement.offsetHeight instead
- Trigger resize event instead of modifying DOM
- Increased delay from 100ms to 150ms for better stability

This should prevent potential conflicts with channel loading and
other page initialization code.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-02 06:56:10 +01:00
MarekWo 35d9d89563 fix: Sync DM read status after modal close and add Android PWA viewport fix
Two critical fixes:

1. DM Badge Sync Issue:
   - After closing DM modal, badge showed correct count for 10 seconds
   - Then auto-refresh (running every 10s) used stale dmLastSeenTimestamps
   - Solution: Call loadDmLastSeenTimestampsFromServer() before updating badge
   - This ensures app.js auto-refresh uses current server state

2. Android PWA Viewport Corruption:
   - Viewport corrupted on F5 refresh in Android PWA mode
   - Status bar content hidden under system UI
   - Solution: Force viewport recalculation on page load
   - Scrolls to top and forces reflow after 100ms delay

Testing needed on Android PWA to verify both fixes work correctly.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-02 06:45:10 +01:00
MarekWo f9827ea06c feat: Replace direct navigation with fullscreen modals for DM and Contact Management
Implement modal dialogs to resolve PWA viewport corruption issues on Android.
When navigating between pages using window.location.href, the viewport height
calculation becomes corrupted, causing the status bar to be hidden under system UI.

Changes:
- Add fullscreen modals for Direct Messages and Contact Management in index.html
- Configure FAB buttons to open modals instead of navigating to new pages
- Add JavaScript to reload iframe content when modals are opened (ensures fresh data)
- Remove DM and Contact Management from offcanvas menu to avoid duplication
- Both modals use iframes to embed existing /dm and /contacts/manage pages
- Modal headers styled with appropriate colors (green for DM, blue for Contacts)

This approach bypasses the viewport corruption issue since modals don't trigger
the problematic navigation flow that occurs with page changes in PWA mode.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-01 19:30:26 +01:00
MarekWo 11935d419a fix: Resolve PWA viewport corruption on page navigation
Root cause: Bootstrap offcanvas leaves backdrop/body classes in DOM
when navigating via window.location.href, causing viewport issues.

Changes:
- Remove hamburger menu button from DM navbar (caused overflow)
- Reduce menu button icon size on channels (remove font-size override)
- Add global navigateTo() function in app.js and contacts.js
- Function closes offcanvas, removes backdrops, clears body classes
- Replace all window.location.href calls with navigateTo()
- Updated navigation in: base.html, contacts*.html templates
- Add 100ms delay before navigation to ensure cleanup completes

This fixes the issue where:
1. Opening offcanvas menu on main page
2. Navigating to DM or Contact Management
3. Returning to main page
Results in corrupted viewport with hidden status bar

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-01 17:31:44 +01:00
MarekWo 5fc1c5b779 feat: Add mention badges, clickable URLs, and image previews to messages
Implemented comprehensive message content enhancements for both channel messages and DMs:

- **Mention badges**: @[Username] mentions now display as styled badges similar to Android Meshcore app
- **Clickable URLs**: http:// and https:// URLs are automatically converted to clickable links that open in new tabs
- **Image thumbnails**: URLs ending in .jpg, .jpeg, .png, .gif, .webp display as thumbnails with click-to-expand modal preview
- **Mobile responsive**: Image thumbnails adapt size for mobile screens
- **Security**: Proper XSS protection with HTML escaping and attribute sanitization

Technical implementation:
- Created shared message-utils.js module for content processing
- Added CSS styles for badges, links, images, and modal preview
- Updated both app.js and dm.js to use new content processor
- Used event delegation for image click handlers to support dynamic content
- Responsive design with mobile-optimized image sizes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 17:21:23 +01:00
MarekWo a53879df97 fix(ui): Move notifications to top-left corner and reduce display time
- Move toast container from bottom-right to top-left corner
- Reduce notification display time from 3-5s to 1.5s
- Prevents notifications from blocking message input area
- Applied consistently across all pages (main, DM, contacts)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-30 12:30:47 +01:00
MarekWo cdc8be9eb4 refactor(contacts): Implement multi-page Contact Management with advanced sorting
Split Contact Management into 3 dedicated pages for improved mobile usability:
- /contacts/manage - Settings & navigation hub (manual approval + cleanup)
- /contacts/pending - Full-screen pending contacts view
- /contacts/existing - Full-screen existing contacts with search/filter/sort

New Features:
- Advanced sorting: Name (A-Z/Z-A) & Last advert (newest/oldest)
- URL-based sort state (?sort=name&order=asc)
- Activity indicators: 🟢 active, 🟡 recent, 🔴 inactive
- Changed terminology: "Last seen" → "Last advert" (more accurate)
- Cleanup tool moved from Settings modal to Contact Management page

Technical Changes:
- Created contacts_base.html standalone template
- Split contacts.html into 3 specialized templates
- Refactored contacts.js for multi-page support with page detection
- Added 2 new Flask routes: /contacts/pending, /contacts/existing
- Removed cleanup section from base.html Settings modal

Mobile-first design: Each page has full-screen space with touch-friendly
navigation and back buttons.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-30 08:40:22 +01:00
MarekWo 77c72ba62e feat: add contact management MVP (manual approval + pending)
Implements Contact Management UI with manual contact approval and pending contacts list.

**Backend changes (meshcore-bridge/bridge.py):**
- Remove forced manual_add_contacts on session init (was for testing only)
- Add _load_webui_settings() to read .webui_settings.json from MC_CONFIG_DIR
- Add /set_manual_add_contacts endpoint for persistent settings management
- Settings now persist across container restarts via .webui_settings.json

**Backend changes (app/meshcore/cli.py):**
- Add get_pending_contacts() - proxy to bridge /pending_contacts
- Add approve_pending_contact() - proxy to bridge /add_pending (always uses full public_key)
- Add get_device_settings() - read .webui_settings.json
- Add set_manual_add_contacts() - proxy to bridge /set_manual_add_contacts

**API changes (app/routes/api.py):**
- Add GET /api/contacts/pending - list pending contacts
- Add POST /api/contacts/pending/approve - approve contact by public_key
- Add GET /api/device/settings - get persistent settings
- Add POST /api/device/settings - update manual_add_contacts setting

**Frontend (app/routes/views.py, templates, js):**
- Add /contacts/manage route rendering contacts.html
- Add contacts.html template with mobile-first design
- Add contacts.js with settings toggle and pending list UI
- Add "Contact Management" menu item in base.html
- Features: manual approval toggle, pending list, approve/copy actions, toast notifications

**Documentation (README.md):**
- Add Contact Management section in Usage
- Add to Key Features list
- Add debugging instructions

**Key features:**
- Manual approval toggle (persists across restarts)
- Pending contacts list with name and public_key
- Approve button (always sends full public_key for compatibility)
- Copy full key button (clipboard API)
- Auto-refresh on page load
- Mobile-first responsive design
- Info badge when manual approval is disabled
- Toast notifications for user feedback

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-29 09:52:09 +01:00
MarekWo 87063c209e fix(dm): Fix mobile menu link and page height issues
- Change DM menu link from <a> to <button> with onclick for better
  mobile compatibility (fixes link not working on some devices)
- Use identical HTML structure as index.html for proper layout
- Remove conflicting inline styles that caused viewport overflow
- Rely on existing style.css rules for body/main flexbox layout

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 08:20:08 +01:00
MarekWo 83b51ab2b9 refactor(dm): Replace modal with full-page view and fix sent DM tracking
- Replace DM modal with full-page view at /dm route for better mobile UX
- Add workaround for meshcore-cli bug where SENT_MSG contains sender's
  name instead of recipient - now saving sent DMs to separate log file
- Fix DM button styling to match Reply button (btn-outline-secondary)
- Add dm.js for DM page functionality
- Add dm.html template with green navbar for visual distinction
- Update menu link to navigate to /dm instead of opening modal
- Remove unused DM modal functions from app.js
- Update documentation with new DM workflow

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 20:27:02 +01:00
MarekWo 1d2cc7fe18 feat: Add direct messages (DM) support
- Parse PRIV (incoming) and SENT_MSG (outgoing) message types
- Add DM API endpoints: conversations, messages, updates
- Implement conversation grouping by pubkey_prefix or name
- Add timeout-based delivery status (pending → timeout)
- Add DM modal with conversation list and thread views
- Add dual notification badge (blue=channels, green=DM)
- Add DM button next to Reply on channel messages
- Include message deduplication for both incoming and outgoing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 17:29:06 +01:00
MarekWo 80e9405449 feat: Add Network Commands section with advert and floodadv
Add new menu section "Network Commands" with two special commands:
- Send Advert: sends single advertisement (recommended for normal use)
- Flood Advert: floods network with advertisement (for recovery only)

Changes:
- cli.py: Add advert() and floodadv() functions
- api.py: Add POST /api/device/command and GET /api/device/commands endpoints
- base.html: Add Network Commands section to slide-out menu
- app.js: Add JavaScript handlers with confirmation for floodadv
- README.md: Document new Network Commands feature

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 11:27:17 +01:00
MarekWo 6c3551cd2d feat: Add support for public channels and auto-cleanup on channel deletion
- Allow joining public channels (starting with #) without encryption key
  - Frontend: Make key field optional with validation for # channels
  - Backend: Update API to accept optional key parameter
  - CLI wrapper: Build meshcli command dynamically based on key presence

- Implement automatic message cleanup when deleting channels
  - Add delete_channel_messages() function to remove channel history
  - Integrate cleanup into DELETE /api/channels endpoint
  - Prevents message leakage when reusing channel slots

- Update documentation with new features and usage instructions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-24 12:34:14 +01:00
MarekWo 927d2a046f feat: Redesign UI for mobile with offcanvas menu and reduced message limit
- Change message byte limit from 200 to 140 bytes
- Remove keyboard hint text to save space
- Simplify navbar to show only notification bell and channel selector
- Add slide-out offcanvas menu for less-used options:
  * Refresh Messages
  * Manage Channels
  * Message History (archive selector)
  * Settings
- Increase font sizes in dropdowns and menu for better readability
- Add icons and text labels to all menu items
- Auto-close menu after selecting options
- Update clipboard API to modern navigator.clipboard with fallback

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-24 08:58:49 +01:00
MarekWo 76134b133a feat: Implement intelligent refresh and multi-channel notifications
Replaces the blind 60-second refresh with a smart polling system that only updates the UI when new messages actually arrive.

Key improvements:
- Lightweight update checks every 10 seconds (vs full refresh every 60s)
- Chat view refreshes only when new messages appear on active channel
- Notification bell with global unread count across all channels
- Per-channel unread badges in channel selector (e.g., "Malopolska (3)")
- Last-seen timestamp tracking per channel with localStorage persistence
- Bell ring animation when new messages arrive

Backend changes:
- New /api/messages/updates endpoint for efficient update polling
- Returns per-channel update status and unread counts

Frontend changes:
- Smart auto-refresh mechanism with conditional UI updates
- Unread message tracking system with localStorage
- Notification bell UI component with badge
- Channel selector badges for unread messages
- CSS animations for bell ring effect

This dramatically reduces network traffic and server load while providing better UX through instant notifications about activity on other channels.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-23 18:12:53 +01:00
MarekWo b223493183 feat: Add responsive design improvements for mobile devices
Improve UI layout on mobile devices (screens < 768px):

Navbar optimizations:
- Hide "Refresh" text on mobile, show only icon to save space
- Reduce gap between navbar elements (0.25rem instead of 0.5rem)
- Decrease min-width for channel/date selectors (80px vs 120px/150px)
- Smaller font-size (0.75rem) and padding for select elements
- Compact button sizes (0.25rem padding)

Modal optimizations:
- Reduce modal margins (0.5rem) for better mobile fit
- Smaller modal-body padding (0.75rem)
- Compact channel keys with smaller font (0.65rem) and word-break
- Reduce list-group-item padding (0.5rem)
- Stack "Add New" and "Join Existing" buttons vertically on very small screens (<400px)

Files changed:
- app/static/css/style.css: Added mobile-specific CSS rules in @media query
- app/templates/base.html: Wrapped "Refresh" text in <span class="btn-text">

Testing: Verified on mobile viewport (iPhone, Android simulators)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-23 07:05:01 +01:00
MarekWo 761e4eac25 feat: Implement full channel management functionality
Add comprehensive channel management features to mc-webui:
- Create new channels with auto-generated encryption keys
- Share channels via QR code or copy-to-clipboard
- Join existing channels with name and key
- Switch between channels in chat interface
- Filter messages by channel
- Persistent channel selection (localStorage)

Backend changes:
- Add CLI wrapper functions: get_channels, add_channel, set_channel, remove_channel
- Modify send_message() to support channel targeting
- Parametrize parser channel filtering (channel_idx parameter)
- Add QR code generation with qrcode + Pillow libraries

API endpoints:
- GET /api/channels - List all channels
- POST /api/channels - Create new channel
- POST /api/channels/join - Join existing channel (auto-detect free slot)
- DELETE /api/channels/<index> - Remove channel
- GET /api/channels/<index>/qr - Generate QR code (JSON or PNG)
- Modified GET /api/messages - Add channel_idx filtering
- Modified POST /api/messages - Add channel_idx targeting

Frontend changes:
- Add channel selector dropdown in navbar
- Add Channels Management modal (create, join, list)
- Add Share Channel modal (QR code, copy key)
- Implement JavaScript channel management logic
- Add event handlers for channel switching
- Persist selected channel in localStorage

QR code format:
{"type":"meshcore_channel","name":"...","key":"..."}

Protection:
- Block deletion of Public channel (index 0)
- Validate channel names (alphanumeric, _, - only)
- Validate encryption keys (32 hex chars)
- Auto-detect free channel slots (1-7)

Backward compatibility:
- Default channel_idx=0 (Public) in all functions
- Existing Public-only code continues to work

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-22 19:04:00 +01:00
MarekWo c6c345a6b6 Feature: Add favicon and PWA manifest for better branding
Added favicon support with multiple sizes for different platforms (16x16, 32x32, 180x180 for Apple, 192x192 and 512x512 for Android). Includes PWA manifest.json for standalone app display with Bootstrap primary theme color.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-22 09:53:32 +01:00
MarekWo f5fedbc96c Feature: Add message archiving system with browse-by-date selector
Implements automatic daily archiving of messages to improve performance
and enable browsing historical chat by date.

Backend changes:
- Add APScheduler for daily archiving at midnight (00:00 UTC)
- Create app/archiver/manager.py with archive logic and scheduler
- Extend parser.py to read from archive files and filter by days
- Add archive configuration to config.py (MC_ARCHIVE_*)

API changes:
- Extend GET /api/messages with archive_date and days parameters
- Add GET /api/archives endpoint to list available archives
- Add POST /api/archive/trigger for manual archiving

Frontend changes:
- Add date selector dropdown in navbar for archive browsing
- Implement archive list loading and date selection
- Update formatTime() to show full dates in archive view
- Live view now shows only last 7 days (configurable)

Docker & Config:
- Add archive volume mount in docker-compose.yml
- Add MC_ARCHIVE_DIR, MC_ARCHIVE_ENABLED, MC_ARCHIVE_RETENTION_DAYS env vars
- Update .env.example with archive configuration section

Documentation:
- Update README.md with archive feature and usage instructions
- Update .claude/instructions.md with archive endpoints

Key features:
- Automatic daily archiving (midnight UTC)
- Live view filtered to last 7 days for better performance
- Browse historical messages by date via dropdown selector
- Archives stored as dated files: {device}.YYYY-MM-DD.msgs
- Original .msgs file never modified (safe, read-only approach)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-21 20:21:33 +01:00
MarekWo 8b36ff78bf Fix: Mobile viewport height issue - use dvh and improve flexbox
Fixed mobile browser viewport height issues where status bar and hint text were hidden:

CSS changes:
- Use 'height: 100dvh' (dynamic viewport height) for mobile browsers
- Fallback to '100vh' for older browsers
- Added 'min-height: 0' to main flex container (critical for flex children)

HTML changes:
- Added 'viewport-fit=cover' to meta tag (notched displays)
- Improved flexbox structure in index.html
- Added inline 'min-height: 0' on flex-grow-1 row (prevents overflow)

The 'dvh' unit dynamically adjusts to browser chrome (URL bar) visibility,
preventing layout shifts when scrolling on mobile. The min-height: 0 fix
ensures flex children properly shrink when needed.

This should fix the issue where bottom status bar disappears on mobile
and top navbar disappears after sending a message.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-21 17:10:11 +01:00
MarekWo cf456422e2 Phase 1: Backend basics - Complete Flask application with REST API
Implemented core backend functionality:
- Flask application structure with blueprints
- Configuration module loading from environment variables
- MeshCore CLI wrapper with subprocess execution and timeout handling
- Message parser for .msgs JSON Lines file format
- REST API endpoints (messages, status, sync, contacts cleanup)
- HTML views with Bootstrap 5 responsive design
- Frontend JavaScript with auto-refresh and live updates
- Custom CSS styling for chat interface

API Endpoints:
- GET  /api/messages - List messages with pagination
- POST /api/messages - Send message with optional reply-to
- GET  /api/status - Device connection status
- POST /api/sync - Trigger message sync
- POST /api/contacts/cleanup - Remove inactive contacts
- GET  /api/device/info - Device information

Features:
- Auto-refresh every 60s (configurable)
- Reply to messages with @[UserName] format
- Toast notifications for feedback
- Settings modal for contact management
- Responsive design (mobile-friendly)
- Message bubbles with sender, timestamp, SNR, hop count

Ready for testing on production server (192.168.131.80:5000)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-21 14:02:46 +01:00