Files
m8chat-app2/help4bis-claude-notes/remaining-work.md

3.9 KiB

Remaining Work — M8Chat App2 (2026-04-11)

P0 — Must test immediately (next session)

  • Test video call with E2EE + COOP/COEP — COOP/COEP headers are now on the server, E2EE is re-enabled in code. Start a call from app2 → Element X mobile. Watch console for:
    • [E2EE] Received encryption key(s) from @user — means key exchange worked
    • worker error — means SharedArrayBuffer still not available (COOP/COEP not working)
    • Scrambled video — key exchange format mismatch with Element X
  • Test hangup termination — end call from app2, verify Element X sees call ended
  • If E2EE worker still crashes: the COOP/COEP headers may break other things (e.g. loading cross-origin resources like Jitsi external_api.js, cached images). Test all features after enabling COEP.

P1 — Important fixes

  • Incoming call detection — MSC3401 state event listener. When Element X starts a call, app2 should show an incoming call UI. Currently nothing happens.
  • Ghost device cleanup — Each web login creates a new device. Need either: (a) periodic admin API cleanup, (b) logout deletes the device, or (c) cron job to purge old M8Chat devices.
  • Rooms provider performance — Room list rebuilds on every sync tick (15+ times visible in console). Should debounce or only rebuild on actual changes.
  • Device ID for APK/iOS — When building native apps, re-enable session persistence and device ID reuse. The secure_storage.dart scaffold exists but is currently neutered for web.

P2 — Quality improvements

  • Noto emoji font — Add NotoColorEmoji font asset to render emoji in room names (currently shows squares)
  • Consolidate key restore dialogs — key_restore_dialog.dart and security_setup_dialog.dart overlap. The security setup already does key restore.
  • Voice-only calling — LiveKit supports audio-only but no UI for it yet
  • Cross-signing verification UX — The Bootstrap flow creates cross-signing keys but there's no UI for verifying other users' devices (emoji comparison)

P3 — Future features

  • Push notifications (Phase 2)
  • Room search (Phase 2 — placeholder in AppBar)
  • Message reactions (partial — display works, sending not implemented)
  • File/image upload (attachment button exists, handler not wired)
  • Read receipts (partial implementation)

Blockers / dependencies

  • E2EE video interop depends on: (1) COOP/COEP working, (2) m.rtc.encryption_keys format matching Element X. If format doesn't match, need to capture what Element X actually sends (check to-device events on Synapse during a test call).
  • COEP may break cross-origin loads — CachedNetworkImage, Jitsi external API, and avatar images from matrix.m8chat.au may fail with require-corp. May need credentialless instead of require-corp, or add crossorigin attributes.

Commands to resume

cd /srv/wp-dev/pwa-sites/m8chat-app2

# Build
flutter build web --release

# Deploy
rsync -avz --delete --exclude='.htaccess' \
  -e "ssh -i ~/.ssh/m8chat_prod -p 2233" \
  build/web/ m8chat@app.m8chat.au:~/public_html/app2.m8chat.au/

# Analyse
dart analyze lib/

# Regenerate Riverpod/Freezed code
dart run build_runner build --delete-conflicting-outputs

# Check Synapse DB
ssh -i ~/.ssh/m8chat_key -p 2233 m8chat_help4bis@chat.m8chat.au \
  "PGPASSWORD=kijPt4cPWkoaZk8BVm psql -h localhost -U synapse_user -d synapse"

# Check deployed .htaccess (COOP/COEP headers)
ssh -i ~/.ssh/m8chat_prod -p 2233 m8chat@app.m8chat.au \
  "cat ~/public_html/app2.m8chat.au/.htaccess"

What next session should start with

  1. /catchup to load these notes
  2. Test video call: app2 → Element X. Paste console output.
  3. If E2EE works → commit everything to Gitea
  4. If E2EE fails → check COEP compatibility issues, may need credentialless mode
  5. If hangup works → move to P1 (incoming call detection)