refactor: Always open Chat Backup as page right after login
This commit is contained in:
parent
34a58c5962
commit
31a204f1ea
8 changed files with 95 additions and 69 deletions
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:matrix/encryption.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
|
|
@ -10,26 +11,21 @@ import 'package:fluffychat/utils/error_reporter.dart';
|
|||
import 'package:fluffychat/utils/fluffy_share.dart';
|
||||
import 'package:fluffychat/utils/localized_exception_extension.dart';
|
||||
import 'package:fluffychat/utils/platform_infos.dart';
|
||||
import 'package:fluffychat/utils/sync_status_localization.dart';
|
||||
import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
|
||||
import 'package:fluffychat/widgets/future_loading_dialog.dart';
|
||||
import '../../utils/adaptive_bottom_sheet.dart';
|
||||
import 'package:fluffychat/widgets/layouts/login_scaffold.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import '../key_verification/key_verification_dialog.dart';
|
||||
|
||||
class BootstrapDialog extends StatefulWidget {
|
||||
final bool wipe;
|
||||
final Client client;
|
||||
|
||||
const BootstrapDialog({
|
||||
super.key,
|
||||
this.wipe = false,
|
||||
required this.client,
|
||||
});
|
||||
|
||||
Future<bool?> show(BuildContext context) => showAdaptiveBottomSheet(
|
||||
context: context,
|
||||
builder: (context) => this,
|
||||
);
|
||||
|
||||
@override
|
||||
BootstrapDialogState createState() => BootstrapDialogState();
|
||||
}
|
||||
|
|
@ -38,7 +34,7 @@ class BootstrapDialogState extends State<BootstrapDialog> {
|
|||
final TextEditingController _recoveryKeyTextEditingController =
|
||||
TextEditingController();
|
||||
|
||||
late Bootstrap bootstrap;
|
||||
Bootstrap? bootstrap;
|
||||
|
||||
String? _recoveryKeyInputError;
|
||||
|
||||
|
|
@ -54,7 +50,7 @@ class BootstrapDialogState extends State<BootstrapDialog> {
|
|||
bool? _wipe;
|
||||
|
||||
String get _secureStorageKey =>
|
||||
'ssss_recovery_key_${bootstrap.client.userID}';
|
||||
'ssss_recovery_key_${bootstrap!.client.userID}';
|
||||
|
||||
bool get _supportsSecureStorage =>
|
||||
PlatformInfos.isMobile || PlatformInfos.isDesktop;
|
||||
|
|
@ -69,18 +65,42 @@ class BootstrapDialogState extends State<BootstrapDialog> {
|
|||
return L10n.of(context).storeSecurlyOnThisDevice;
|
||||
}
|
||||
|
||||
late final Client client;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_createBootstrap(widget.wipe);
|
||||
super.initState();
|
||||
client = Matrix.of(context).client;
|
||||
_createBootstrap(widget.wipe);
|
||||
}
|
||||
|
||||
void _cancelAction() async {
|
||||
final consent = await showOkCancelAlertDialog(
|
||||
context: context,
|
||||
title: L10n.of(context).skipChatBackup,
|
||||
message: L10n.of(context).skipChatBackupWarning,
|
||||
okLabel: L10n.of(context).skip,
|
||||
isDestructive: true,
|
||||
);
|
||||
if (consent != OkCancelResult.ok) return;
|
||||
if (!mounted) return;
|
||||
_goBackAction(false);
|
||||
}
|
||||
|
||||
void _goBackAction(bool success) =>
|
||||
context.canPop() ? context.pop(success) : context.go('/rooms');
|
||||
|
||||
void _createBootstrap(bool wipe) async {
|
||||
await client.roomsLoading;
|
||||
await client.accountDataLoading;
|
||||
await client.userDeviceKeysLoading;
|
||||
while (client.prevBatch == null) {
|
||||
await client.onSync.stream.first;
|
||||
}
|
||||
_wipe = wipe;
|
||||
titleText = null;
|
||||
_recoveryKeyStored = false;
|
||||
bootstrap =
|
||||
widget.client.encryption!.bootstrap(onUpdate: (_) => setState(() {}));
|
||||
bootstrap = client.encryption!.bootstrap(onUpdate: (_) => setState(() {}));
|
||||
final key = await const FlutterSecureStorage().read(key: _secureStorageKey);
|
||||
if (key == null) return;
|
||||
_recoveryKeyTextEditingController.text = key;
|
||||
|
|
@ -89,22 +109,45 @@ class BootstrapDialogState extends State<BootstrapDialog> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
final bootstrap = this.bootstrap;
|
||||
if (bootstrap == null) {
|
||||
return LoginScaffold(
|
||||
appBar: AppBar(
|
||||
centerTitle: true,
|
||||
leading: CloseButton(onPressed: _cancelAction),
|
||||
title: Text(L10n.of(context).loadingMessages),
|
||||
),
|
||||
body: Center(
|
||||
child: StreamBuilder(
|
||||
stream: client.onSyncStatus.stream,
|
||||
builder: (context, snapshot) {
|
||||
final status = snapshot.data;
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
CircularProgressIndicator.adaptive(value: status?.progress),
|
||||
if (status != null) Text(status.calcLocalizedString(context)),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_wipe ??= widget.wipe;
|
||||
final buttons = <Widget>[];
|
||||
Widget body = const CircularProgressIndicator.adaptive();
|
||||
Widget body = const Center(child: CircularProgressIndicator.adaptive());
|
||||
titleText = L10n.of(context).loadingPleaseWait;
|
||||
|
||||
if (bootstrap.newSsssKey?.recoveryKey != null &&
|
||||
_recoveryKeyStored == false) {
|
||||
final key = bootstrap.newSsssKey!.recoveryKey;
|
||||
titleText = L10n.of(context).recoveryKey;
|
||||
return Scaffold(
|
||||
return LoginScaffold(
|
||||
appBar: AppBar(
|
||||
centerTitle: true,
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.close),
|
||||
onPressed: Navigator.of(context).pop,
|
||||
),
|
||||
leading: CloseButton(onPressed: _cancelAction),
|
||||
title: Text(L10n.of(context).recoveryKey),
|
||||
),
|
||||
body: Center(
|
||||
|
|
@ -220,14 +263,11 @@ class BootstrapDialogState extends State<BootstrapDialog> {
|
|||
break;
|
||||
case BootstrapState.openExistingSsss:
|
||||
_recoveryKeyStored = true;
|
||||
return Scaffold(
|
||||
return LoginScaffold(
|
||||
appBar: AppBar(
|
||||
centerTitle: true,
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.close),
|
||||
onPressed: Navigator.of(context).pop,
|
||||
),
|
||||
title: Text(L10n.of(context).chatBackup),
|
||||
leading: CloseButton(onPressed: _cancelAction),
|
||||
title: Text(L10n.of(context).setupChatBackup),
|
||||
),
|
||||
body: Center(
|
||||
child: ConstrainedBox(
|
||||
|
|
@ -373,16 +413,14 @@ class BootstrapDialogState extends State<BootstrapDialog> {
|
|||
context: context,
|
||||
delay: false,
|
||||
future: () async {
|
||||
await widget.client.updateUserDeviceKeys();
|
||||
return widget.client
|
||||
.userDeviceKeys[widget.client.userID!]!
|
||||
await client.updateUserDeviceKeys();
|
||||
return client.userDeviceKeys[client.userID!]!
|
||||
.startVerification();
|
||||
},
|
||||
);
|
||||
if (req.error != null) return;
|
||||
await KeyVerificationDialog(request: req.result!)
|
||||
.show(context);
|
||||
Navigator.of(context, rootNavigator: false).pop();
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
|
@ -446,8 +484,7 @@ class BootstrapDialogState extends State<BootstrapDialog> {
|
|||
body = const Icon(Icons.error_outline, color: Colors.red, size: 80);
|
||||
buttons.add(
|
||||
ElevatedButton(
|
||||
onPressed: () =>
|
||||
Navigator.of(context, rootNavigator: false).pop<bool>(false),
|
||||
onPressed: () => _goBackAction(false),
|
||||
child: Text(L10n.of(context).close),
|
||||
),
|
||||
);
|
||||
|
|
@ -472,8 +509,7 @@ class BootstrapDialogState extends State<BootstrapDialog> {
|
|||
);
|
||||
buttons.add(
|
||||
ElevatedButton(
|
||||
onPressed: () =>
|
||||
Navigator.of(context, rootNavigator: false).pop<bool>(false),
|
||||
onPressed: () => _goBackAction(false),
|
||||
child: Text(L10n.of(context).close),
|
||||
),
|
||||
);
|
||||
|
|
@ -481,14 +517,9 @@ class BootstrapDialogState extends State<BootstrapDialog> {
|
|||
}
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
return LoginScaffold(
|
||||
appBar: AppBar(
|
||||
leading: Center(
|
||||
child: CloseButton(
|
||||
onPressed: () =>
|
||||
Navigator.of(context, rootNavigator: false).pop<bool>(true),
|
||||
),
|
||||
),
|
||||
leading: CloseButton(onPressed: _cancelAction),
|
||||
title: Text(titleText ?? L10n.of(context).loadingPleaseWait),
|
||||
),
|
||||
body: Center(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue