pop until contact view after sucessfull verification
Some checks are pending
Flutter analyze & test / flutter_analyze_and_test (push) Waiting to run

This commit is contained in:
otsmr 2026-07-18 20:25:28 +02:00
parent bb8f33e9d6
commit 6284345b57
4 changed files with 99 additions and 58 deletions

View file

@ -3,6 +3,7 @@ import 'dart:typed_data';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:cryptography_plus/cryptography_plus.dart'; import 'package:cryptography_plus/cryptography_plus.dart';
import 'package:flutter/material.dart';
import 'package:twonly/locator.dart'; import 'package:twonly/locator.dart';
import 'package:twonly/src/database/daos/contacts.dao.dart'; import 'package:twonly/src/database/daos/contacts.dao.dart';
import 'package:twonly/src/database/tables/contacts.table.dart'; import 'package:twonly/src/database/tables/contacts.table.dart';
@ -17,6 +18,24 @@ import 'package:twonly/src/utils/misc.dart';
import 'package:twonly/src/visual/components/verification_success_dialog.comp.dart'; import 'package:twonly/src/visual/components/verification_success_dialog.comp.dart';
class KeyVerificationService { class KeyVerificationService {
static final StreamController<void> _verificationSuccessCloseController =
StreamController<void>.broadcast();
static Stream<void> get onVerificationSuccessClose =>
_verificationSuccessCloseController.stream;
static void notifyVerificationSuccessClose() {
_verificationSuccessCloseController.add(null);
}
static void closeVerificationFlows(BuildContext context) {
Navigator.popUntil(context, (route) {
final name = route.settings.name;
if (name == null) return false;
return !name.contains('qr_scanner') && !name.contains('verifybadge');
});
}
static Future<List<int>> getNewSecretVerificationToken() async { static Future<List<int>> getNewSecretVerificationToken() async {
final token = getRandomUint8List(16); final token = getRandomUint8List(16);
await twonlyDB.keyVerificationDao.insertVerificationToken(token); await twonlyDB.keyVerificationDao.insertVerificationToken(token);

View file

@ -1,9 +1,11 @@
import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:qr_flutter/qr_flutter.dart'; import 'package:qr_flutter/qr_flutter.dart';
import 'package:twonly/src/database/daos/contacts.dao.dart'; import 'package:twonly/src/database/daos/contacts.dao.dart';
import 'package:twonly/src/database/twonly.db.dart'; import 'package:twonly/src/database/twonly.db.dart';
import 'package:twonly/src/services/key_verification.service.dart';
import 'package:twonly/src/utils/avatars.dart'; import 'package:twonly/src/utils/avatars.dart';
import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/misc.dart';
import 'package:twonly/src/utils/qr.utils.dart'; import 'package:twonly/src/utils/qr.utils.dart';
@ -22,8 +24,19 @@ class ProfileQrCodeComp extends StatefulWidget {
BuildContext context, { BuildContext context, {
Contact? contact, Contact? contact,
bool openToVerify = false, bool openToVerify = false,
}) { }) async {
return showModalBottomSheet( StreamSubscription<void>? subscription;
if (openToVerify) {
subscription = KeyVerificationService.onVerificationSuccessClose.listen((_) {
if (context.mounted) {
KeyVerificationService.closeVerificationFlows(context);
}
});
}
try {
await showModalBottomSheet<void>(
context: context, context: context,
isScrollControlled: true, isScrollControlled: true,
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
@ -75,6 +88,9 @@ class ProfileQrCodeComp extends StatefulWidget {
); );
}, },
); );
} finally {
await subscription?.cancel();
}
} }
@override @override

View file

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:twonly/src/database/daos/contacts.dao.dart'; import 'package:twonly/src/database/daos/contacts.dao.dart';
import 'package:twonly/src/database/twonly.db.dart'; import 'package:twonly/src/database/twonly.db.dart';
import 'package:twonly/src/services/key_verification.service.dart';
import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/misc.dart';
import 'package:twonly/src/visual/components/avatar_icon.comp.dart'; import 'package:twonly/src/visual/components/avatar_icon.comp.dart';
import 'package:twonly/src/visual/components/verification_success_animation.comp.dart'; import 'package:twonly/src/visual/components/verification_success_animation.comp.dart';
@ -18,11 +19,16 @@ class VerificationSuccessDialog extends StatelessWidget {
final String? message; final String? message;
/// Utility method to easily present this dialog. /// Utility method to easily present this dialog.
static Future<void> show(BuildContext context, Contact contact, {String? message}) { static Future<void> show(
BuildContext context,
Contact contact, {
String? message,
}) {
return showDialog<void>( return showDialog<void>(
context: context, context: context,
barrierDismissible: false, barrierDismissible: false,
builder: (context) => VerificationSuccessDialog(contact: contact, message: message), builder: (context) =>
VerificationSuccessDialog(contact: contact, message: message),
); );
} }
@ -75,7 +81,10 @@ class VerificationSuccessDialog extends StatelessWidget {
), ),
const SizedBox(height: 28), const SizedBox(height: 28),
MyButton( MyButton(
onPressed: () => Navigator.pop(context), onPressed: () {
KeyVerificationService.notifyVerificationSuccessClose();
Navigator.pop(context);
},
child: Text(context.lang.close), child: Text(context.lang.close),
), ),
], ],

View file

@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
import 'package:twonly/src/database/daos/contacts.dao.dart'; import 'package:twonly/src/database/daos/contacts.dao.dart';
import 'package:twonly/src/database/twonly.db.dart'; import 'package:twonly/src/database/twonly.db.dart';
import 'package:twonly/src/services/key_verification.service.dart';
import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/misc.dart';
import 'package:twonly/src/visual/views/camera/camera_preview_components/camera_preview.dart'; import 'package:twonly/src/visual/views/camera/camera_preview_components/camera_preview.dart';
import 'package:twonly/src/visual/views/camera/camera_preview_components/camera_preview_controller_view.dart'; import 'package:twonly/src/visual/views/camera/camera_preview_components/camera_preview_controller_view.dart';
@ -34,11 +35,7 @@ class QrCodeScannerViewState extends State<QrCodeScannerView> {
if (widget.openToVerify && widget.contact != null) { if (widget.openToVerify && widget.contact != null) {
_mainCameraController.onVerificationSuccessDismissed = (contact) { _mainCameraController.onVerificationSuccessDismissed = (contact) {
if (mounted) { if (mounted) {
Navigator.popUntil(context, (route) { KeyVerificationService.closeVerificationFlows(context);
final name = route.settings.name;
if (name == null) return true;
return !name.contains('qr_scanner') && !name.contains('verifybadge');
});
} }
}; };
} }