mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-07-19 14:04:08 +00:00
pop until contact view after sucessfull verification
Some checks are pending
Flutter analyze & test / flutter_analyze_and_test (push) Waiting to run
Some checks are pending
Flutter analyze & test / flutter_analyze_and_test (push) Waiting to run
This commit is contained in:
parent
bb8f33e9d6
commit
6284345b57
4 changed files with 99 additions and 58 deletions
|
|
@ -3,6 +3,7 @@ import 'dart:typed_data';
|
|||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:cryptography_plus/cryptography_plus.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:twonly/locator.dart';
|
||||
import 'package:twonly/src/database/daos/contacts.dao.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';
|
||||
|
||||
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 {
|
||||
final token = getRandomUint8List(16);
|
||||
await twonlyDB.keyVerificationDao.insertVerificationToken(token);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:qr_flutter/qr_flutter.dart';
|
||||
import 'package:twonly/src/database/daos/contacts.dao.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/misc.dart';
|
||||
import 'package:twonly/src/utils/qr.utils.dart';
|
||||
|
|
@ -22,59 +24,73 @@ class ProfileQrCodeComp extends StatefulWidget {
|
|||
BuildContext context, {
|
||||
Contact? contact,
|
||||
bool openToVerify = false,
|
||||
}) {
|
||||
return showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
backgroundColor: Colors.transparent,
|
||||
builder: (context) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: context.color.surface,
|
||||
borderRadius: const BorderRadius.vertical(
|
||||
top: Radius.circular(24),
|
||||
}) async {
|
||||
StreamSubscription<void>? subscription;
|
||||
|
||||
if (openToVerify) {
|
||||
subscription = KeyVerificationService.onVerificationSuccessClose.listen((_) {
|
||||
if (context.mounted) {
|
||||
KeyVerificationService.closeVerificationFlows(context);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
await showModalBottomSheet<void>(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
backgroundColor: Colors.transparent,
|
||||
builder: (context) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: context.color.surface,
|
||||
borderRadius: const BorderRadius.vertical(
|
||||
top: Radius.circular(24),
|
||||
),
|
||||
),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(vertical: 24, horizontal: 20),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const SizedBox(width: double.infinity),
|
||||
Container(
|
||||
width: 40,
|
||||
height: 4,
|
||||
decoration: BoxDecoration(
|
||||
color: context.color.onSurface.withValues(alpha: 0.2),
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
padding: const EdgeInsets.symmetric(vertical: 24, horizontal: 20),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const SizedBox(width: double.infinity),
|
||||
Container(
|
||||
width: 40,
|
||||
height: 4,
|
||||
decoration: BoxDecoration(
|
||||
color: context.color.onSurface.withValues(alpha: 0.2),
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
Text(
|
||||
openToVerify
|
||||
? (contact != null
|
||||
? context.lang.letUserScanQrCode(
|
||||
getContactDisplayName(contact),
|
||||
)
|
||||
: context.lang.letFriendScanQrToVerify)
|
||||
: (contact != null
|
||||
? context.lang.letUserScanQrCode(
|
||||
getContactDisplayName(contact),
|
||||
)
|
||||
: context.lang.addContactQrSheetSubtext),
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: context.color.onSurface.withValues(alpha: 0.6),
|
||||
const SizedBox(height: 24),
|
||||
Text(
|
||||
openToVerify
|
||||
? (contact != null
|
||||
? context.lang.letUserScanQrCode(
|
||||
getContactDisplayName(contact),
|
||||
)
|
||||
: context.lang.letFriendScanQrToVerify)
|
||||
: (contact != null
|
||||
? context.lang.letUserScanQrCode(
|
||||
getContactDisplayName(contact),
|
||||
)
|
||||
: context.lang.addContactQrSheetSubtext),
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: context.color.onSurface.withValues(alpha: 0.6),
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
const ProfileQrCodeComp(),
|
||||
const SizedBox(height: 34),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
const SizedBox(height: 24),
|
||||
const ProfileQrCodeComp(),
|
||||
const SizedBox(height: 34),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
} finally {
|
||||
await subscription?.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:twonly/src/database/daos/contacts.dao.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/visual/components/avatar_icon.comp.dart';
|
||||
import 'package:twonly/src/visual/components/verification_success_animation.comp.dart';
|
||||
|
|
@ -18,11 +19,16 @@ class VerificationSuccessDialog extends StatelessWidget {
|
|||
final String? message;
|
||||
|
||||
/// 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>(
|
||||
context: context,
|
||||
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),
|
||||
MyButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
onPressed: () {
|
||||
KeyVerificationService.notifyVerificationSuccessClose();
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text(context.lang.close),
|
||||
),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:twonly/src/database/daos/contacts.dao.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/visual/views/camera/camera_preview_components/camera_preview.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) {
|
||||
_mainCameraController.onVerificationSuccessDismissed = (contact) {
|
||||
if (mounted) {
|
||||
Navigator.popUntil(context, (route) {
|
||||
final name = route.settings.name;
|
||||
if (name == null) return true;
|
||||
return !name.contains('qr_scanner') && !name.contains('verifybadge');
|
||||
});
|
||||
KeyVerificationService.closeVerificationFlows(context);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue