dev
dart 211 lines 7.91 KB
Raw
1 import 'package:cake_wallet/core/totp_request_details.dart';
2 import 'package:cake_wallet/src/screens/base_page.dart';
3 import 'package:cake_wallet/src/screens/receive/widgets/qr_image.dart';
4 import 'package:cake_wallet/src/widgets/primary_button.dart';
5 import 'package:cake_wallet/src/widgets/standard_list.dart';
6 import 'package:cake_wallet/generated/i18n.dart';
7 import 'package:cake_wallet/routes.dart';
8 import 'package:cake_wallet/utils/clipboard_util.dart';
9 import 'package:cake_wallet/utils/show_bar.dart';
10 import 'package:cake_wallet/view_model/set_up_2fa_viewmodel.dart';
11 import 'package:flutter/material.dart';
12 import 'package:flutter/services.dart';
13 import 'package:qr_flutter/qr_flutter.dart' as qr;
14 import 'package:url_launcher/url_launcher.dart';
15
16 class Setup2FAQRPage extends BasePage {
17 Setup2FAQRPage({required this.setup2FAViewModel});
18
19 final Setup2FAViewModel setup2FAViewModel;
20
21 @override
22 String get title => S.current.setup_2fa;
23
24 @override
25 Widget body(BuildContext context) {
26 final copyImage = Image.asset('assets/images/copy_content.png',
27 height: 16, width: 16, color: Theme.of(context).colorScheme.onSurface);
28 final cake2FAHowToUseUrl = Uri.parse(
29 'https://docs.cakewallet.com/features/advanced/authentication/#enabling-cake-2fa');
30 return Padding(
31 padding: const EdgeInsets.symmetric(horizontal: 24),
32 child: Column(
33 children: [
34 Spacer(),
35 Text(
36 S.current.scan_qr_on_device,
37 style: Theme.of(context).textTheme.bodyMedium!.copyWith(
38 fontWeight: FontWeight.w700,
39 height: 1.5714,
40 ),
41 ),
42 SizedBox(height: 10),
43 ConstrainedBox(
44 constraints: BoxConstraints(maxHeight: MediaQuery.of(context).size.height * 0.3),
45 child: AspectRatio(
46 aspectRatio: 1.0,
47 child: Container(
48 padding: EdgeInsets.all(5),
49 decoration: BoxDecoration(
50 border: Border.all(
51 width: 3,
52 color: Theme.of(context).colorScheme.onSurface,
53 ),
54 ),
55 child: Container(
56 child: QrImage(
57 data: setup2FAViewModel.totpVersionOneLink,
58 version: qr.QrVersions.auto,
59 foregroundColor: Theme.of(context).colorScheme.onSurface,
60 backgroundColor: Colors.transparent,
61 )),
62 ),
63 ),
64 ),
65 SizedBox(height: 26),
66 Text(
67 S.current.add_secret_code,
68 style: Theme.of(context).textTheme.bodyMedium!.copyWith(
69 fontWeight: FontWeight.w700,
70 height: 1.5714,
71 ),
72 ),
73 Row(
74 mainAxisAlignment: MainAxisAlignment.spaceBetween,
75 crossAxisAlignment: CrossAxisAlignment.center,
76 children: [
77 Expanded(
78 flex: 2,
79 child: Column(
80 crossAxisAlignment: CrossAxisAlignment.start,
81 children: [
82 Text(
83 S.current.totp_secret_code,
84 style: Theme.of(context).textTheme.bodySmall!.copyWith(
85 fontWeight: FontWeight.w500,
86 color: Theme.of(context).colorScheme.onSurfaceVariant,
87 height: 1.8333,
88 ),
89 ),
90 SizedBox(height: 8),
91 Text(
92 '${setup2FAViewModel.totpSecretKey}',
93 style: Theme.of(context)
94 .textTheme
95 .bodyMedium!
96 .copyWith(fontSize: 18, color: Theme.of(context).colorScheme.onSurface),
97 maxLines: 1,
98 overflow: TextOverflow.ellipsis,
99 ),
100 ],
101 ),
102 ),
103 SizedBox(width: 8),
104 Container(
105 width: 32,
106 height: 32,
107 child: InkWell(
108 onTap: () {
109 ClipboardUtil.setSensitiveDataToClipboard(
110 ClipboardData(text: '${setup2FAViewModel.totpSecretKey}'));
111 showBar<void>(context, S.of(context).copied_to_clipboard);
112 },
113 child: Container(
114 child: copyImage,
115 ),
116 ),
117 )
118 ],
119 ),
120 SizedBox(height: 8),
121 StandardListSeparator(),
122 SizedBox(height: 13),
123 Row(
124 mainAxisAlignment: MainAxisAlignment.spaceBetween,
125 crossAxisAlignment: CrossAxisAlignment.center,
126 children: [
127 Expanded(
128 flex: 2,
129 child: Column(
130 crossAxisAlignment: CrossAxisAlignment.start,
131 children: [
132 Text(
133 S.current.totp_auth_url,
134 style: Theme.of(context).textTheme.bodySmall!.copyWith(
135 fontWeight: FontWeight.w500,
136 color: Theme.of(context).colorScheme.onSurfaceVariant,
137 height: 1.8333,
138 ),
139 ),
140 SizedBox(height: 8),
141 Text(
142 '${setup2FAViewModel.totpVersionOneLink}',
143 style: Theme.of(context)
144 .textTheme
145 .bodyMedium!
146 .copyWith(fontSize: 18, color: Theme.of(context).colorScheme.onSurface),
147 maxLines: 1,
148 overflow: TextOverflow.ellipsis,
149 ),
150 ],
151 ),
152 ),
153 SizedBox(width: 8),
154 Container(
155 width: 32,
156 height: 32,
157 child: InkWell(
158 onTap: () {
159 ClipboardUtil.setSensitiveDataToClipboard(
160 ClipboardData(text: '${setup2FAViewModel.totpVersionOneLink}'));
161 showBar<void>(context, S.of(context).copied_to_clipboard);
162 },
163 child: Container(
164 child: copyImage,
165 ),
166 ),
167 )
168 ],
169 ),
170 SizedBox(height: 8),
171 StandardListSeparator(),
172 SizedBox(height: 16),
173 GestureDetector(
174 onTap: () => _launchUrl(cake2FAHowToUseUrl),
175 child: Row(
176 mainAxisSize: MainAxisSize.min,
177 mainAxisAlignment: MainAxisAlignment.center,
178 children: [
179 Text(S.current.how_to_use,
180 style: Theme.of(context).textTheme.bodyMedium!.copyWith(
181 decoration: TextDecoration.underline,
182 fontSize: 16,
183 fontWeight: FontWeight.w500,
184 color: Theme.of(context).colorScheme.onSurface)),
185 Icon(Icons.info_outline, size: 20, color: Theme.of(context).colorScheme.onSurface)
186 ],
187 )),
188 Spacer(flex: 5),
189 PrimaryButton(
190 onPressed: () {
191 Navigator.of(context).pushReplacementNamed(Routes.totpAuthCodePage,
192 arguments: TotpAuthArgumentsModel(
193 isForSetup: true,
194 ));
195 },
196 text: S.current.continue_text,
197 color: Theme.of(context).colorScheme.primary,
198 textColor: Theme.of(context).colorScheme.onPrimary,
199 ),
200 SizedBox(height: 24),
201 ],
202 ),
203 );
204 }
205
206 static void _launchUrl(Uri url) async {
207 try {
208 await launchUrl(url, mode: LaunchMode.externalApplication);
209 } catch (e) {}
210 }
211 }