Commit Graph
95 Commits
Author SHA1 Message Date
MarekWoandClaude Opus 5 6dc2fc0a0e docs: note the sudo case in the GitHub HTTP/2 workaround
--global writes to the config of whoever runs it, so a user updating with sudo was still prompted after applying the fix. Confirmed by a user on Raspberry Pi OS.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-02 21:57:07 +02:00
MarekWoandClaude Opus 5 01efc396dc docs: banner the GitHub HTTP/2 update block at the top of the README
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-02 21:21:14 +02:00
MarekWoandClaude Opus 5 4df984b2e0 fix(update): stop mcupdate asking for a GitHub username
GitHub's HTTP/2 front end began answering the anonymous git-upload-pack
POST with 401 for the git 2.39 / libcurl 7.88 build that ships with
Debian 12. Git reads any 401 as a credential request, so update.sh sat
on "Username for 'https://github.com':" against a public repo, on every
server at once, with nothing changed locally.

Pull with http.version=HTTP/1.1, which GitHub still serves anonymously,
and set GIT_TERMINAL_PROMPT=0 so a genuine auth failure errors out
instead of blocking on stdin forever. Documented in troubleshooting,
README and whatsnew, including the one-off git config for installs too
old to carry the fix.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-02 21:09:41 +02:00
MarekWoandClaude Opus 5 be0929a3ae feat(demo): read-only demo mode for a publicly shared instance
mc-webui has no login, which is fine on a LAN and not fine once the
address is handed to testers: they assume the node is theirs and rename
it, and the console is right there for anyone curious enough to type
into it.

MC_DEMO=true refuses everything that reconfigures the radio, destroys
data, reaches other people's repeaters, rebuilds the containers,
publishes to an external broker, or hands out a secret. Reading and
sending messages keep working, so the instance is still worth visiting.

The guard is default-deny: an api_bp.before_request hook refuses every
non-GET unless it is on a short allowlist, so an endpoint added later is
locked without touching this module. That mattered — six mutating
endpoints already had no frontend caller and would never have made a
hand-written blacklist. A small read denylist covers the GETs that leak
(repeater passwords, backup download, capture download, /api/logs),
which the write guard never sees.

Two paths bypass the HTTP layer and are closed separately: the console
is a Socket.IO event, not a route, so it is checked against a read-only
command set; the log viewer is refused at the connect handshake.

Access is kept two ways. MC_DEMO_TRUSTED_NETS unlocks by CIDR, and
MC_DEMO_UNLOCK_CODE unlocks by a code typed once in Settings and held in
an HMAC cookie for 30 days — stateless, and deliberately not Flask's
session, whose SECRET_KEY is a hardcoded public constant.

The trap the network list walks into: published through a tunnel, every
visitor arrives from the tunnel's address, and if the tunnel runs on the
LAN then trusting the LAN unlocks the instance for the whole internet.
An address arriving with a proxy header is therefore not matched unless
MC_TRUST_PROXY is on, and startup logs report the resulting shape.

Frontend is advisory only: demo-lock.js loads from _head_i18n.html so it
reaches all eight entry points including the six iframes, greys out
[data-demo-lock] rather than hiding it (the instance exists to show the
app off), re-applies via MutationObserver for JS-rendered buttons, and
turns any 403 demo_locked into a toast.

Verified on the local container: the rename, reboot, updater, vacuum,
cleanup and the leaky GETs all 403; sending, read markers and ordinary
reads pass; `set name` is refused over the console socket while `infos`
still answers; unlock/lock round-trips. 86 new unit tests, en/pl at 100%.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 18:20:53 +02:00
MarekWoandClaude Opus 5 05ec5fa13e feat(https): optional HTTPS front end via Nginx Proxy Manager
Adds an opt-in HTTPS layer without touching anything for existing installs.

The proxy is a service in docker-compose.yml behind the "https" Compose
profile, activated with COMPOSE_PROFILES=https in .env. That keeps the whole
setup inside files git owns while the switch lives in a file it ignores --
important because scripts/update.sh runs `git pull`, so any user edit to a
tracked compose file would break the next update with a merge conflict.
mcupdate needs no change: compose reads COMPOSE_PROFILES from .env itself.

Both services share the project's default network, so the proxy forwards to
http://mc-webui:5000 internally; MC_BIND_ADDRESS lets the plain-HTTP port be
restricted to loopback once HTTPS works, and MC_TRUST_PROXY turns on ProxyFix
so the app sees the real client address and scheme.

Also fixes copying over plain HTTP. navigator.clipboard only exists in a
secure context, and 9 call sites across 5 entry points used it with no
fallback, so copy buttons silently did nothing on a LAN address. They now
share clipboard-utils.js, loaded via _head_i18n.html (the one include every
entry point already has), which falls back to execCommand.

Verified locally against the real stack: self-signed cert uploaded to NPM,
proxy host created, app served over HTTPS with socket.io upgrading to a real
wss:// WebSocket (transport "websocket"), and the clipboard fallback checked
end-to-end by pasting back what it copied over http://.

Two findings from that run are documented in docs/https-setup.md:
NPM 2.15 dropped the default admin@example.com account for a setup wizard,
and its default 443 server now refuses connections without SNI -- which is
every connection made to a bare IP address. docker/npm-default-site.conf is
the opt-in way around that, mounted writable (a :ro mount aborts s6 init and
leaves nginx not listening at all).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 17:58:03 +02:00
MarekWoandClaude Opus 5 f71cac8b2e feat(android): ship the Android companion app with an install guide
A thin WebView wrapper that opens a user's own mc-webui instance full
screen, without the browser address bar. It asks once for the server
address and remembers it; all logic stays on the server.

- android/mc-webui-wrapper.apk (1.0, it.wojtaszek.mc.wrapper, minSdk 21)
- docs/android-app.md: download + checksum, "unknown sources" permission,
  the Play Protect notice, first connection, and the limitations that come
  with a WebView (no notifications, no QR camera, no file downloads)
- README, user guide and whatsnew entries, incl. an app-vs-PWA comparison
- *.apk marked binary so the text=auto rule can never touch it

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-28 20:55:04 +02:00
MarekWoandClaude Opus 5 993013e0f5 docs: say which version a branch is showing
The Releases panel on GitHub is repository-wide, so browsing dev still
shows the latest stable release in the sidebar - which reads as "dev is
2.1.0" when dev is actually preparing 2.2.0. A note at the top of the
README points at the VERSION file, which is per-branch and therefore
always right.

Deliberately carries no version number of its own: it explains how to
read the two sources rather than duplicating them, so it needs no upkeep
and merges between branches without conflicting.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 08:22:15 +02:00
MarekWoandClaude Opus 5 4c6857a00f feat: numbered releases (2.1.0) with git tags and GitHub releases
The app already knew exactly which build was running - a calendar version
of commit date plus short hash - but nothing gave a release a name users
could quote, and the repo had no tags at all.

Adds a VERSION file as the single source of truth for a SemVer release
number, read by app/version.py alongside the existing build string rather
than replacing it: the number is for people, the build is for pinning down
a deploy, and both ship in /api/version and the template context. The menu
shows the release first with the build underneath. #versionText still holds
the build string, because the remote-update poller compares it to detect
that the server came back on a new build.

Resolution order is unchanged (frozen file > git > fallback), and a frozen
file written before this change still yields a correct release number, so
an already-deployed server does not need re-freezing to stay sane. The
container has no git, hence COPY VERSION into the image - otherwise a plain
'docker compose build' reports 0.0.0.

scripts/release.sh cuts a release from main: it refuses a dirty tree, a
wrong branch, a malformed number or an existing tag, extracts the notes
from the matching whatsnew section, then tags, pushes and publishes via gh.

Numbering starts at 2.1.0 rather than 1.x: the v2 line has been in
production since March and 'v1' is the archived pre-migration branch, so
1.x would have been ambiguous. Sections in whatsnew before 2.1.0 keep
their date-only headings - they were never tagged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-26 19:20:57 +02:00
MarekWo 87b30f63b3 docs: Update Meshcore flasher URL 2026-07-14 20:41:03 +02:00
MarekWoandClaude Opus 4.6 0a08759065 docs: sync README, user guide, and architecture with recent features
Catch up on ~36 commits since b60c99a. Document Device Settings tab
(public info + radio) with map picker and regional presets, quick-access
FAB cluster with drag/collapse/sizing, configurable route popup and toast
timeout/position, multi-arch Docker images (amd64, arm64, arm/v7), and
new endpoints /api/device/config and /api/ui/settings.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 16:14:57 +02:00
MarekWoandClaude Opus 4.6 8aac3d4839 ci: add dual registry (Docker Hub + GHCR) and dev branch builds
- Push images to both Docker Hub and GitHub Container Registry
- Build on main (latest tag) and dev (dev tag) branches
- Update README with Docker Hub installation instructions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-01 15:35:33 +02:00
MarekWoandClaude Opus 4.6 b60c99aad1 docs: update documentation for BLE transport, DM retry scenarios, and path_hash_mode
Add new docs to README table (DM retry logic, BLE pairing guide), update
architecture diagram and DB schema for BLE/delivery tracking, rewrite DM
retry settings section in user guide to reflect 4-scenario matrix, add BLE
troubleshooting reference, and update .claude/context files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 19:50:43 +02:00
MarekWoandClaude Opus 4.6 054b80926d docs: update documentation for path management, add contact, theme, sidebar
- README: add multi-path routing, add contact via URI/QR, dark/light theme,
  desktop sidebar, device share tab, pubkey-based DB naming
- User Guide: add sections for Adding Contacts (URI/QR/manual), DM Path
  Management (multi-path, repeater picker, map picker, keep path toggle),
  Device Share tab, theme setting, desktop sidebar notes
- Architecture: add path management API endpoints (CRUD, reorder, reset,
  no_auto_flood), manual-add, push-to-device, move-to-cache endpoints,
  update DB naming to pubkey prefix

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 18:08:58 +01:00
MarekWoandClaude Opus 4.6 66ada3d03c docs: comprehensive documentation update for v2 features
Update all documentation to reflect features added since last doc update:
- README: new features list, gallery screenshots, development status
- User Guide: global search, console commands, device dashboard, settings,
  system log, backup, updated DM and contact management sections
- Architecture: complete API reference, WebSocket namespaces, updated
  project structure and database tables
- Troubleshooting: remove v1 bridge references, add UI-based backup,
  system log references
- Gallery: add 4 new screenshots (search, filtering, settings, system log),
  update 12 existing screenshots

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 16:26:52 +01:00
MarekWo 653d8d8646 docs: update public documentation to reflect v2 architecture and features 2026-03-11 08:07:22 +01:00
MarekWoandClaude Opus 4.6 28148d32d8 feat: Deterministic echo-to-message matching via pkt_payload computation
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>
2026-02-21 07:29:49 +01:00
MarekWoandClaude Opus 4.6 2ed3dc3758 feat: Add unknown delivery status indicator + update docs
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>
2026-02-19 08:14:58 +01:00
MarekWoandClaude Opus 4.6 b9a9436271 feat: Enhance echo tracking with paths, incoming routes, and persistence
- 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>
2026-02-07 15:59:41 +01:00
MarekWoandClaude Opus 4.5 96efc2a716 docs: Add watchdog documentation and fix executable flags
- Added docs/watchdog.md with installation and usage guide
- Added watchdog reference to README.md documentation table
- Fixed executable permissions on watchdog scripts

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 13:43:17 +01:00
MarekWoandClaude Opus 4.5 c18863c903 docs: Add echo tracking feature to README
- Added "Echo tracking" to Key Features section
- Added "Echo Tracking" to Completed Features checklist

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 21:50:53 +01:00
MarekWoandClaude Opus 4.5 38f51b909a feat: Add resend button and adjust message byte limits
- 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>
2026-01-26 20:46:03 +01:00
MarekWoandClaude Opus 4.5 2ef9e94ab8 docs: Add @mentions autocomplete to README
- Add to Key Features section
- Add to Completed Features checklist

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 08:31:34 +01:00
MarekWo a4baa438c5 docs: Minor update of README 2026-01-24 21:13:39 +01:00
MarekWo d726407bcc docs: Add support link to buycoffee.to 2026-01-24 10:04:54 +01:00
MarekWoandClaude Opus 4.5 fb94c62f63 docs: Add contact protection to Key Features
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 21:00:26 +01:00
MarekWo 6f1b61a488 docs: Minor README.md update (gallery) 2026-01-22 08:40:24 +01:00
MarekWoandClaude Opus 4.5 7f99d9886a docs: Add remote update screenshots to Gallery
Add 3 new screenshots showing the remote update workflow:
- Update Available, Remote Update, Updated Successfully

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 08:35:42 +01:00
MarekWo baf338ae27 docs: Cosmetic change in README.md 2026-01-22 08:23:18 +01:00
MarekWoandClaude Opus 4.5 df852a1a80 feat: Add remote update capability from web GUI
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>
2026-01-21 16:58:05 +01:00
MarekWo 976d9c6822 docs: Update README to reflect support for Heltec V3 and add DeepWiki badge 2026-01-21 10:44:38 +01:00
MarekWoandClaude Opus 4.5 59a05b9649 docs: Add Gallery section to README with clickable thumbnails
Add HTML table with 150px thumbnail previews of all screenshots.
Images are clickable to view full size. Updated and added new
screenshots for menu, map, console, and image preview features.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 08:05:33 +01:00
MarekWo 828caaaf98 docs: Screenshot gallery moved out of README 2026-01-20 21:42:15 +01:00
MarekWoandClaude Opus 4.5 0dc66b8f3c feat: Add update script for easier upgrades
- Add scripts/update.sh with colored output and error handling
- Automates: git pull, version freeze, docker compose rebuild
- Update README with script usage and alias instructions

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 16:27:18 +01:00
MarekWoandClaude Opus 4.5 1e6f47dcde docs: Add version freeze to installation instructions
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 12:10:35 +01:00
MarekWoandClaude Opus 4.5 cd165415e9 docs: Add version freeze step to update instructions
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 11:56:26 +01:00
MarekWoandClaude Opus 4.5 72da96e647 feat: Add Leaflet map for contact locations
- 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>
2026-01-15 22:46:36 +01:00
MarekWoandClaude Opus 4.5 45e96b9bb7 docs: Simplify installation - auto-detect works by default
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>
2026-01-15 15:27:49 +01:00
MarekWoandClaude Opus 4.5 b2496b17b0 feat: Auto-detect serial port from /dev/serial/by-id/
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>
2026-01-15 15:18:07 +01:00
MarekWoandClaude Opus 4.5 b8a77285ab docs: Add MC_DEVICE_NAME=auto as recommended setting
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>
2026-01-15 12:26:58 +01:00
MarekWo 6000750e6c docs: Add update instructions and testing guidelines for mc-webui 2026-01-12 09:51:37 +01:00
MarekWoandClaude Opus 4.5 1e22041d42 docs: Add Interactive Console to features and usage
- 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>
2026-01-09 21:49:00 +01:00
MarekWoandClaude Opus 4.5 0a44a9d792 docs: Reorganize and simplify documentation structure
- 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>
2026-01-07 10:21:55 +01:00
MarekWoandClaude Sonnet 4.5 a5c00e2329 docs: Reorganize Prerequisites section and fix references
- Move device preparation from Installation step 0 to Prerequisites
- Restructure Prerequisites into logical sections:
  1. Meshcore Device setup (flashing and configuration)
  2. Linux Server requirements (git, Docker)
- Replace wiki.wojtaszek.it link with local DOCKER_INSTALL.md reference
- Remove Installation step 0, renumber steps to start from 1
- Fix typo: "can used" -> "can use" (line 121)
- Improve readability with "Before starting, ensure you have:" intro

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-06 17:48:41 +01:00
MarekWoandClaude Sonnet 4.5 9180aa4ac9 docs: Refactor installation documentation and fix typos
- Fix typos in README.md installation section:
  - "Chose" -> "Choose"
  - "prepeare" -> "prepare"
  - Fix code block formatting (line 156-158)
  - Fix markdown formatting (line 254)
- Add COMMON_ISSUES.md for troubleshooting (separate from README)
- Add DOCKER_INSTALL.md with Docker installation guide
- Add installation guide images
- Remove FRESH_INSTALL.md (consolidated into README)
- Remove MIGRATION.md (no longer needed)
- Update version date to 2026-01-06 in COMMON_ISSUES.md

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-06 17:42:39 +01:00
MarekWoandClaude Sonnet 4.5 4bd6a681db feat: Add local emoji picker for complete offline independence
Complete the offline support implementation by hosting emoji-picker-element locally, eliminating the last external CDN dependency. Application now works 100% offline without any internet connection.

Changes:
- Download and host emoji-picker-element 1.28.1 locally (~100 KB)
  - index.js, picker.js, database.js
- Download and host emoji data JSON (~429 KB)
  - en/emojibase/data.json with full emoji database
- Update index.html and dm.html:
  - Replace CDN emoji picker import with local version
  - Also migrate Bootstrap CSS/JS to local in dm.html (was missed before)
- Configure emoji picker to use local data source in app.js and dm.js
  - Set picker.dataSource to local JSON path
- Update Service Worker (v2 → v3):
  - Add emoji picker files to pre-cache list
  - Total offline cache size: ~1.2 MB
- Update documentation:
  - README.md: Add emoji picker to offline support features
  - CLAUDE.md: Document emoji picker implementation and file structure

Total offline package breakdown:
- Bootstrap CSS/JS: ~307 KB
- Bootstrap Icons: ~398 KB
- Emoji Picker: ~100 KB
- Emoji Data: ~429 KB
- Total: ~1.2 MB

Benefits:
- Zero external dependencies (no CDN calls)
- Full emoji picker functionality offline
- Faster page load (no external requests)
- Perfect for air-gapped mesh network deployments

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-05 21:26:26 +01:00
MarekWoandClaude Sonnet 4.5 964d88a14a feat: Add full offline support with local Bootstrap libraries
Implement complete offline functionality by hosting Bootstrap CSS/JS and icons locally, eliminating dependency on external CDNs. This ensures the application works reliably in internet-free environments, perfect for mesh networks in remote or emergency scenarios.

Changes:
- Download and host Bootstrap 5.3.2 CSS/JS locally (~307 KB total)
- Download and host Bootstrap Icons 1.11.2 CSS and fonts (~300 KB)
- Update base.html to use local library paths instead of CDN URLs
- Enhance Service Worker with hybrid caching strategy:
  - Cache-first for vendor libraries (static, unchanging)
  - Network-first for app code (dynamic, needs updates)
- Bump Service Worker cache version to v2
- Add vendor libraries to pre-cache list for instant offline availability
- Update README.md with offline support documentation
- Update project structure documentation

Benefits:
- Works without internet connection (no CDN dependency)
- Faster initial page load (no external requests)
- Reliable operation during internet outages
- Perfect for air-gapped and remote mesh network deployments

File sizes:
- Bootstrap CSS: ~227 KB
- Bootstrap JS: ~80 KB
- Bootstrap Icons CSS: ~98 KB
- Bootstrap Icons Fonts: ~300 KB (woff2 + woff)

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-05 20:46:27 +01:00
MarekWo e0a946233d add: Diagram 2026-01-05 17:44:59 +01:00
MarekWo 4d51942548 chore: Update image gallery 2026-01-05 16:55:34 +01:00
MarekWoandClaude Sonnet 4.5 5ceb6f638a docs: Add PWA notifications documentation to README
Updates README.md for the new PWA notification feature:

- Added PWA notifications to Key Features list with platform support notes
- Created comprehensive "PWA Notifications (Experimental)" section in Usage:
  - How to enable/disable notifications
  - Platform support (tested on Windows/Firefox, Android requires testing)
  - Installing as PWA instructions for Android and Desktop
  - Troubleshooting guide
- Added to Completed Features checklist
- Updated Project Structure to include sw.js and manifest.json

Testing status:
- ✅ Windows Desktop (Firefox) - working correctly
- ⚠️ Android Mobile - requires further testing (PWA via Chrome)

Note: .claude/CLAUDE.md also updated but excluded from git (in .gitignore)

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-05 15:28:13 +01:00
MarekWoandClaude Sonnet 4.5 34ab437390 feat: Remember last selected DM conversation
Add localStorage persistence for Direct Messages page to remember and restore the last selected conversation when user returns to the page.

Changes:
- Save selected conversation to localStorage when user selects a conversation
- Restore last conversation on page load (if no URL parameter provided)
- Clear localStorage when user returns to empty state
- Updated README.md with persistence documentation
- Priority: URL parameter > localStorage > empty state

This improves UX by maintaining conversation context across page navigation, similar to how the main page remembers the selected channel.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-04 13:29:04 +01:00