feat: encrypted-history prompt, incoming-call alerts, message edit, panic button (v1.7.0+11)

P1 key_restore_prompt: offer recovery-key restore right after login
P2 incoming calls: mount overlay in app.dart + detect MSC3401 call.member
   (Element X signalling) — calls were previously invisible
P3 message edit: editMessage/EditMessage + Edit dialog (reactions/delete
   were already wired)
P5 panic button: new feature/panic module — hold-to-send alert text +
   m.location to a configured room; alert sent before geolocation so a
   denied permission never blocks it

All verified end-to-end in headless Chromium against production build.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-04 07:30:57 +10:00
parent 923c0ad878
commit a36df1c961
15 changed files with 700 additions and 30 deletions

View File

@@ -1,12 +1,17 @@
// Version: 1.5.0 | Created: 2026-04-01 | Updated: 2026-04-27
// Version: 1.6.0 | Created: 2026-04-01 | Updated: 2026-07-04
// Main rooms list screen with bottom navigation.
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'dart:async';
import '../../../core/network/matrix_client.dart';
import '../../help/presentation/help_tab.dart';
import '../../panic/presentation/panic_button.dart';
import '../../jitsi/presentation/conference_tab.dart';
import '../../profile/presentation/key_restore_prompt.dart';
import '../../profile/presentation/profile_screen.dart';
import '../../spaces/presentation/spaces_screen.dart';
import 'public_rooms_dialog.dart';
@@ -27,6 +32,17 @@ class _RoomsScreenState extends ConsumerState<RoomsScreen> {
String _searchQuery = '';
final _searchController = TextEditingController();
@override
void initState() {
super.initState();
// Offer encrypted-history restore right after login (fires once).
WidgetsBinding.instance.addPostFrameCallback((_) {
if (!mounted) return;
final client = ref.read(matrixClientProvider);
unawaited(maybePromptKeyRestore(context, client));
});
}
@override
void dispose() {
_searchController.dispose();
@@ -99,6 +115,7 @@ class _RoomsScreenState extends ConsumerState<RoomsScreen> {
)
: const Text('M8Chat'),
actions: [
const PanicButton(),
IconButton(
icon: Icon(_searchActive ? Icons.close : Icons.search),
tooltip: _searchActive ? 'Cancel search' : 'Search rooms',