Commit Graph

77 Commits

Author SHA1 Message Date
MarekWo
815adb5cfa feat(bridge): Add pending contacts management API endpoints
Added two new HTTP endpoints to meshcore-bridge for managing pending contacts
(contacts awaiting manual approval when manual_add_contacts mode is enabled):

New endpoints:
- GET /pending_contacts - List all pending contacts awaiting approval
  - Parses meshcli output format: "Name: <hex_public_key>"
  - Returns JSON array with {name, public_key} objects
  - Includes raw_stdout for debugging

- POST /add_pending - Approve and add a pending contact
  - Accepts JSON body: {"selector": "<name_or_pubkey>"}
  - Validates selector is non-empty string
  - Executes meshcli add_pending command via persistent session

Additional changes:
- Added curl to mc-webui Dockerfile for testing endpoints
- Updated README with Testing Bridge API section
- Included example curl commands and expected responses

Implementation notes:
- Uses existing MeshCLISession.execute_command() - no new processes
- Same persistent session and command queue architecture
- Consistent error handling with existing /cli endpoint

Enables future UI for manual contact approval workflow.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-29 08:09:35 +01:00
MarekWo
ee7dde4ca2 fix(cli): Replace 'public' command with 'chan 0' to fix quote handling
Issue: Messages sent to Public channel had visible double quotes around
multi-word text (e.g., "Hello world" appeared as "Hello world" in chat).

Root cause: In interactive mode, meshcli's 'public' command treats quotes
literally as part of message content, while 'chan' command correctly parses
them as argument delimiters.

Solution: Use 'chan 0' for Public channel instead of 'public' command.
This ensures consistent quote handling across all channels.

Before:
- Public (ch 0): public "message" → quotes visible in output
- Other channels: chan <nb> "message" → quotes correctly parsed ✓

After:
- All channels: chan <nb> "message" → consistent behavior ✓

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-28 20:46:06 +01:00
MarekWo
ff0d52e281 docs: Update documentation for persistent meshcli session architecture
Updated documentation to reflect the fundamental architectural change from
per-request subprocess spawning to a persistent meshcli session in meshcore-bridge.

Changes:
- Updated README.md with detailed bridge session architecture section
- Added TZ environment variable to configuration table
- Created comprehensive technical note (technotes/persistent-meshcli-session.md)
  documenting the refactor, implementation details, and benefits

Key architectural changes documented:
- Single subprocess.Popen with stdin/stdout pipes (not subprocess.run per request)
- Multiplexing: JSON adverts → .adverts.jsonl log, CLI responses → HTTP
- Real-time message reception via msgs_subscribe (no polling required)
- Thread-safe command queue with event-based synchronization
- Watchdog thread for automatic crash recovery
- Timeout-based response detection (300ms idle threshold)

This persistent session enables:
 Real-time message reception without polling
 Network advertisement logging
 Advanced interactive features (manual_add_contacts, etc.)
 Better stability and lower latency

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-28 18:10:32 +01:00
MarekWo
3a100e742d fix(bridge): Correct command name from msg_subscribe to msgs_subscribe 2025-12-28 17:14:09 +01:00
MarekWo
d720d6a263 fix(bridge): Replace polling with msg_subscribe for real-time messages
Critical fixes based on user feedback:

1. **Remove auto-recv polling (30s interval)**
   - Polling with 'recv' doesn't fetch NEW messages, only reads from .msgs
   - Wasteful - creates unnecessary command traffic

2. **Add msg_subscribe for real-time message reception**
   - meshcli's msg_subscribe enables automatic message events
   - Messages arrive via EventType.CHANNEL_MSG_RECV events
   - No polling needed - truly asynchronous

3. **Make TZ configurable via .env instead of hardcoded**
   - Changed docker-compose.yml: TZ=${TZ:-UTC}
   - Added TZ=Europe/Warsaw to .env.example
   - Users can now set their own timezone

4. **Remove unused shlex import**
   - Not needed after switching to manual double-quote wrapping

Technical details:
- msg_subscribe sends subscription command to meshcli at init
- meshcli then emits events when messages arrive
- Events trigger TTY errors (harmless - meshcli tries to print_above)
- Messages are still saved to .msgs file by meshcli core

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-28 17:10:33 +01:00
MarekWo
34c60515ad fix(bridge): Add auto-recv thread to sync messages every 30s
CRITICAL FIX: Messages stopped arriving after switching to persistent session.
Root cause: meshcli in interactive mode (Popen stdin/stdout) doesn't receive
messages automatically - requires explicit 'recv' command.

Changes:
- Add auto_recv_thread that calls 'recv' every 30 seconds in background
- This ensures continuous message synchronization without breaking /cli
- Messages are saved to .msgs file by meshcli as usual
- Add TZ=Europe/Warsaw to both containers for correct timestamps in logs

Technical details:
- auto-recv runs in separate thread via command queue (no blocking)
- First recv after 5s delay (let session initialize)
- Uses execute_command() internally, so respects command serialization
- Thread stops gracefully on shutdown_flag

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-28 16:59:32 +01:00
MarekWo
36badea5a2 fix(bridge): Use double quotes instead of shlex.quote for message args
Users reported single quotes appearing in sent messages.
shlex.quote() uses single quotes which meshcli treats literally.

Changes:
- Replace shlex.quote() with custom double-quote wrapping
- Only quote args containing spaces or special chars
- Escape internal double quotes with backslash
- Example: ['public', 'To jest test'] → 'public "To jest test"'

meshcli should strip double quotes but preserve content.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-28 15:55:42 +01:00
MarekWo
56b7c335e8 fix(bridge): Quote command arguments to preserve spaces in messages
Users reported messages with spaces were truncated to first word.
Root cause: ' '.join(args) didn't quote arguments with spaces.

Changes:
- Import shlex module
- Use shlex.quote() for each argument in execute_command()
- Example: ['public', 'To jest test'] → "public 'To jest test'"

This ensures meshcli receives multi-word messages correctly.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-28 15:52:06 +01:00
MarekWo
693b211a71 fix(bridge): Replace echo markers with timeout-based response detection
meshcli doesn't support 'echo' command, causing "Unknown command" errors.
Changed strategy from end-markers to timeout-based detection:

- Remove echo "___END_{cmd_id}___" markers
- Add _monitor_response_timeout() thread per command
- Track last_line_time timestamp for each response
- Complete command when no new lines received for 300ms
- Update _append_to_current_response() to update timestamps

This approach is more robust and doesn't depend on meshcli's command set.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-28 15:44:53 +01:00
MarekWo
34afa6908d feat(bridge): Implement persistent meshcli session with advert logging
Major refactor of meshcore-bridge to maintain a single long-lived meshcli
process instead of spawning new processes per request.

Changes:
- Add MeshCLISession class managing persistent subprocess.Popen session
- Implement thread-safe command queue with event-based synchronization
- Add stdout/stderr reader threads with JSON advert detection
- Log adverts automatically to {device_name}.adverts.jsonl with timestamp
- Add end-of-response markers (echo "___END_{cmd_id}___") for multiplexing
- Implement watchdog thread for auto-restart on meshcli crash
- Update /cli endpoint to delegate commands through persistent session
- Add MC_CONFIG_DIR and MC_DEVICE_NAME env vars to docker-compose.yml

Architecture benefits:
- No more USB port conflicts between concurrent requests
- Continuous advert logging without breaking /cli compatibility
- Better error recovery with automatic session restart
- Reduced overhead from process spawning

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-28 15:41:41 +01:00
MarekWo
9cd763c8c5 fix(dm): Remove DM button from messages and filter only CLI contacts
Two improvements to DM functionality:

1. Removed DM button from message blocks in channel view
   - Users should use the DM page directly instead
   - Cleaner UI without redundant buttons

2. Filter only CLI (client) contacts in DM dropdown
   - Added filter_types parameter to parse_contacts()
   - get_contacts_list() now returns only CLI contacts
   - Repeaters (REP), rooms (ROOM), and sensors (SENS) are excluded
   - You can't send DMs to repeaters anyway!

Updated README.md to reflect these changes.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-28 15:23:43 +01:00
MarekWo
2e009b2d3e refactor(dm): Show all contacts in DM dropdown selector
Changed DM approach from conditional button visibility to showing all
available contacts directly in the DM page dropdown. This provides better
UX and performance.

Changes:
- Reverted conditional DM button visibility in app.js (button always shows)
- Removed contacts loading from main page (app.js)
- Added loadContacts() function to dm.js to fetch contacts from API
- Modified populateConversationSelector() to show:
  1. Existing conversations (with history) first
  2. Separator: "--- Available contacts ---"
  3. All contacts from device who aren't in conversations yet
- Users can now start new DM conversations with any contact
- Updated README.md with new DM workflow description

Benefits:
- Simpler and more intuitive UX
- Better performance (no checks on every message)
- Users can proactively start conversations
- Clear visibility of who's available for DM

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-28 15:15:50 +01:00
MarekWo
94528c2a96 fix(parser): Fix contacts parsing to include emoji and spaces in names
Previous regex stopped at first space, causing names like "daniel5120 🔫"
to be parsed as just "daniel5120", breaking DM button visibility checks.

Changed parsing logic to split by 2+ consecutive spaces (column separator
in meshcli output) and extract full contact name before type column.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-28 14:59:23 +01:00
MarekWo
40a9b4e3bf feat: Conditional DM button visibility based on contacts list
The DM button is now only shown for users who are in the device's contacts
list, ensuring that direct messages will actually be delivered. This prevents
users from attempting to send DMs to recipients who cannot receive them.

Changes:
- Added parse_contacts() and get_contacts_list() functions to cli.py for parsing
  meshcli contacts output
- Created /api/contacts endpoint to retrieve contact names from device
- Modified frontend app.js to fetch and cache contacts list on page load
- Updated createMessageElement() to conditionally render DM button only when
  sender is in contacts list
- Updated README.md with note about DM button visibility requirement

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-28 14:31:14 +01:00
MarekWo
de79c04dee Merge branch 'dev' 2025-12-28 09:46:53 +01:00
MarekWo
3d681f57ee fix(parser): Use sender field for SENT_CHAN in meshcore-cli 1.3.12+
Fix channel message sender name display. In meshcore-cli 1.3.12, the 'name'
field in SENT_CHAN entries now contains the channel name instead of the
sender's device name. Update parser to use the 'sender' field instead.

Before: Sent messages showed "channel 0" as sender
After: Sent messages correctly show "MarWoj" (actual sender name)

This change is consistent with the SENT_MSG parsing for Direct Messages.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-28 07:15:24 +01:00
MarekWo
f02fa718aa docs: Add meshcore-cli 1.3.12 version requirement to README
Add explicit requirement for meshcore-cli >= 1.3.12 in Prerequisites section.
This version is required for proper Direct Messages (DM) functionality due
to the fix of SENT_MSG format (recipient and sender fields).

Related: Refactoring commit 879f704

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-28 07:08:40 +01:00
MarekWo
ec9a037c0a docs: Add meshcore-cli 1.3.12 version requirement to README
Add explicit requirement for meshcore-cli >= 1.3.12 in Prerequisites section.
This version is required for proper Direct Messages (DM) functionality due
to the fix of SENT_MSG format (recipient and sender fields).

Related: Refactoring commit 879f704

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-27 20:51:09 +01:00
MarekWo
0ddcedca27 docs: Update README to include MIT license badge and add contact section 2025-12-27 20:43:13 +01:00
MarekWo
879f7041e7 refactor(dm): Use native SENT_MSG from meshcore-cli 1.3.12+ instead of custom log
Remove workaround for meshcore-cli 1.3.11 bug where SENT_MSG contained
sender name instead of recipient. Now using native SENT_MSG entries from
.msgs file with correct recipient and sender fields (requires meshcore-cli >= 1.3.12).

Changes:
- Add _parse_sent_msg() to parse SENT_MSG from .msgs file
- Update read_dm_messages() to process both PRIV and SENT_MSG from .msgs
- Remove save_sent_dm(), _read_sent_dm_log(), _parse_sent_dm_entry()
- Remove dm_sent_log_path property from config
- Add _cleanup_old_dm_sent_log() to remove obsolete log file
- Update comments and documentation

Benefits:
- Single source of truth (.msgs file only)
- Simpler codebase (-95 lines)
- No custom workarounds
- Better data consistency

Related: meshcore-cli update to 1.3.12 (commit ad4a7b3)

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-27 19:48:39 +01:00
MarekWo
ad4a7b3f49 build(bridge): Update meshcore-cli to version 1.3.12
Fix critical bug in private message logging that prevented proper DM tracking.

Previous version (1.3.11) logged sent private messages with incomplete data:
- Missing recipient information
- Only included sender name in 'name' field
- Format: {"type": "SENT_MSG", "name": "MarWoj", "text": "...", ...}

Updated version (1.3.12) includes both sender and recipient:
- Added 'recipient' field with recipient's device name
- Added 'sender' field with sender's name
- Format: {"type": "SENT_MSG", "recipient": "SP7UNR_tdeck", "sender": "MarWoj", "name": "SP7UNR_tdeck", ...}

This fix enables proper message tracking in the DM module, as it now correctly
identifies both parties in private message exchanges.

Fix requested from meshcore-cli maintainers and implemented in v1.3.12.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-27 18:52:26 +01:00
MarekWo
fd014dfa4a fix(dm): Fix mobile menu link and page height issues - third attempt 2025-12-26 08:56:00 +01:00
MarekWo
9b28c360ba fix(dm): Temporarily shortened Direct Messages to DM on the header od the DM page. 2025-12-26 08:44:31 +01:00
MarekWo
fe6cc7db51 fix(dm): Fix mobile menu link and page height issues - second attempt 2025-12-26 08:39:48 +01:00
MarekWo
f7057b62e3 Merge branch 'dev' of https://github.com/MarekWo/mc-webui into dev 2025-12-26 08:20:44 +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
6f351f8bc1 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)
- Add proper flexbox layout styles for DM page viewport height
- Use 100dvh (dynamic viewport height) for mobile browsers
- Add flex-shrink: 0 to form and status bar to prevent overflow
- Reduce padding in form and status bar for more compact mobile view

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 08:11:56 +01:00
MarekWo
2788b92687 fix(dm): Improve DM UI consistency and fix conversation merging
- Fix duplicate conversations in dropdown by merging pk_ and name_ IDs
- Add intelligent refresh (only reload when new messages arrive)
- Fix message alignment (own messages right, others left)
- Change sent message status from 'timeout' to 'pending'
- Add emoji picker button to DM page
- Change message limit from 200 to 140 bytes (consistent with channels)
- Update README.md with corrected DM documentation

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 22:29:57 +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
47911884b3 docs: Update Roadmap section and remove PRD references
- Restructured Development Status section to reflect completed work
- Replaced phase-based roadmap with Completed Features and Next Steps
- Added all implemented features to completed list
- Included Private Messages (DM) as next planned feature
- Removed references to hidden PRD.md file

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-24 14:56:00 +01:00
MarekWo
679cc77e69 fix: meshcore-cli project URL 2025-12-24 14:41:16 +01:00
MarekWo
6063f11dfc docs: Add LICENSE document 2025-12-24 14:38:43 +01:00
MarekWo
666b9e8fb4 chore: Replace screenshot with English version 2025-12-24 14:33:09 +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
4401aaf980 docs: Minor update in README 2025-12-24 11:08:38 +01:00
MarekWo
4a4c6894a2 chore: Update hidden files list 2 2025-12-24 11:06:11 +01:00
MarekWo
4581a943e1 chore: Update hidden files list 2025-12-24 11:05:03 +01:00
MarekWo
739c10c748 add: meshcore-cli documentation 2025-12-24 11:03:01 +01:00
MarekWo
78c59f6bc7 chore: Remove outdated documentation files for channels, limits, meshcore-cli, and smart refresh feature 2025-12-24 11:02:42 +01:00
MarekWo
2e6d09421e fix: Add space between images in README 2025-12-24 09:29:27 +01:00
MarekWo
5d7bf7f181 fix: Update image distribution on README 2025-12-24 09:27:52 +01:00
MarekWo
c4b560676b Refactor code structure for improved readability and maintainability 2025-12-24 09:23:40 +01:00
MarekWo
4b0d495c37 docs: Update README.md for new UI and message limit
- Update message limit from 200 chars to 140 bytes
- Add mobile-first design as key feature
- Update instructions for accessing menu-based features:
  * Managing Channels now via slide-out menu
  * Message Archives now via slide-out menu
- Reflect new offcanvas menu navigation

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-24 09:07:49 +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
3588469a47 chore: Remove version info from docker-compose.yml 2025-12-24 08:15:04 +01:00
MarekWo
c19a5bac88 fix: Add request locking and caching to prevent USB conflicts
Root cause: Multiple concurrent meshcli calls were fighting for USB access,
causing "Protocol error" and 504 Gateway Timeouts.

Changes to meshcore-bridge:
- Add threading.Lock to serialize meshcli subprocess calls
- Prevent concurrent USB access that causes OSError [Errno 71]
- Reduce DEFAULT_TIMEOUT from 30s to 10s
- Add detailed logging for lock acquisition and release

Changes to main API:
- Implement 30s cache for get_channels() to reduce USB calls
- Cache invalidation after channel create/join/delete operations
- Use cached channels in /api/channels and /api/messages/updates
- Reduce HTTP timeout from 30s to 12s (10s bridge + 2s buffer)

Impact:
- Eliminates race conditions when page loads (multiple API calls)
- Prevents USB port conflicts and protocol errors
- Faster response times due to caching
- No need for manual USB resets after container restarts

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-23 22:02:57 +01:00
MarekWo
a494f6b47d fix: Resolve channel dropdown disappearing issue
- Add timeout protection (10s for channels, 15s for updates)
- Implement fallback mechanism to ensure Public channel always exists
- Fix race condition by loading channels before setupAutoRefresh()
- Add proper validation for API responses and channel data
- Improve error handling with detailed logging
- Prevent checkForUpdates() from running before channels are loaded

This fixes the recurring issue where the channel dropdown would
randomly become empty, especially visible on mobile devices.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-23 21:44:34 +01:00
MarekWo
c8a2201c8c docs: Update documentation for smart refresh and notifications
Update README.md and .claude/instructions.md to reflect new features:
- Intelligent refresh mechanism (10s polling vs 60s full refresh)
- Notification bell with global unread counter
- Per-channel unread badges
- New /api/messages/updates endpoint

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-23 21:17:04 +01:00