dev
dart 198 lines 7.59 KB
Raw
1 import 'package:cake_wallet/core/execution_state.dart';
2 import 'package:cake_wallet/generated/i18n.dart';
3 import 'package:cake_wallet/new-ui/widgets/keyboard_hide_overlay.dart';
4 import 'package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart';
5 import 'package:cake_wallet/src/screens/dashboard/widgets/sign_form.dart';
6 import 'package:cake_wallet/src/screens/dashboard/widgets/verify_form.dart';
7 import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
8 import 'package:cake_wallet/src/widgets/primary_button.dart';
9
10 import 'package:cake_wallet/utils/show_pop_up.dart';
11 import 'package:cake_wallet/view_model/dashboard/sign_view_model.dart';
12 import 'package:flutter/material.dart';
13 import 'package:flutter_mobx/flutter_mobx.dart';
14 import 'package:mobx/mobx.dart';
15 import 'package:smooth_page_indicator/smooth_page_indicator.dart';
16
17 class SignPage extends StatefulWidget {
18 SignPage(this.signViewModel);
19
20 final SignViewModel signViewModel;
21
22 @override
23 State<SignPage> createState() => _SignPageState();
24 }
25
26 class _SignPageState extends State<SignPage> {
27 List<Widget> _pages = [];
28 final signFormKey = GlobalKey<SignFormState>();
29 final verifyFormKey = GlobalKey<VerifyFormState>();
30 final PageController _controller = PageController(initialPage: 0);
31
32 bool _isEffectsInstalled = false;
33
34 void initState() {
35 super.initState();
36 _pages.add(SignForm(
37 key: signFormKey,
38 type: widget.signViewModel.wallet.type,
39 chainId: widget.signViewModel.wallet.chainId,
40 includeAddress: widget.signViewModel.signIncludesAddress,
41 ));
42 _pages.add(VerifyForm(
43 key: verifyFormKey,
44 type: widget.signViewModel.wallet.type,
45 chainId: widget.signViewModel.wallet.chainId,
46 ));
47 }
48
49 @override
50 Widget build(BuildContext context) {
51 _setEffects(context);
52
53 return Container(
54 color: Theme.of(context).colorScheme.surface,
55 child: SafeArea(
56 top: false,
57 child: Column(
58 children: [
59 ModalTopBar(
60 title: S.current.sign_verify_title,
61 leadingIcon: Icon(Icons.arrow_back_ios_new),
62 leadingSemanticLabel: S.current.seed_alert_back,
63 onLeadingPressed: Navigator.of(context).pop,
64 ),
65 Expanded(
66 child: KeyboardHideOverlay(
67 child: Container(
68 height: 0,
69 color: Theme.of(context).colorScheme.surface,
70 child: Center(
71 child: Column(
72 mainAxisAlignment: MainAxisAlignment.center,
73 children: [
74 Expanded(
75 child: PageView.builder(
76 onPageChanged: (page) {
77 widget.signViewModel.isSigning = page == 0;
78 },
79 controller: _controller,
80 itemCount: _pages.length,
81 itemBuilder: (_, index) => SingleChildScrollView(child: _pages[index]),
82 ),
83 ),
84 if (_pages.length > 1)
85 Padding(
86 padding: EdgeInsets.only(top: 10),
87 child: SmoothPageIndicator(
88 controller: _controller,
89 count: _pages.length,
90 effect: ColorTransitionEffect(
91 spacing: 6.0,
92 radius: 6.0,
93 dotWidth: 6.0,
94 dotHeight: 6.0,
95 dotColor: Theme.of(context).colorScheme.outline.withOpacity(0.5),
96 activeDotColor: Theme.of(context).colorScheme.outline,
97 ),
98 ),
99 ),
100 Padding(
101 padding: EdgeInsets.only(top: 20, bottom: 24, left: 24, right: 24),
102 child: Column(
103 children: [
104 Observer(
105 builder: (context) {
106 return LoadingPrimaryButton(
107 onPressed: () async {
108 await _confirmForm(context);
109 },
110 text: widget.signViewModel.isSigning
111 ? S.current.sign_message
112 : S.current.verify_message,
113 color: Theme.of(context).colorScheme.primary,
114 textColor: Theme.of(context).colorScheme.onPrimary,
115 isLoading: widget.signViewModel.state is IsExecutingState,
116 isDisabled: widget.signViewModel.state is IsExecutingState,
117 );
118 },
119 ),
120 ],
121 ),
122 )
123 ],
124 ),
125 ),
126 ),
127 ),
128 ),
129 ],
130 ),
131 ),
132 );
133 }
134
135 void _setEffects(BuildContext context) async {
136 if (_isEffectsInstalled) {
137 return;
138 }
139 _isEffectsInstalled = true;
140
141 reaction((_) => widget.signViewModel.state, (ExecutionState state) {
142 if (state is FailureState) {
143 WidgetsBinding.instance.addPostFrameCallback((_) {
144 showPopUp<void>(
145 context: context,
146 builder: (_context) {
147 return AlertWithOneAction(
148 alertTitle: S.current.error,
149 alertContent: state.error,
150 buttonText: S.of(context).ok,
151 buttonAction: () {
152 if (context.mounted && Navigator.canPop(_context)) Navigator.of(_context).pop();
153 },
154 );
155 });
156 });
157 }
158 if (state is ExecutedSuccessfullyState) {
159 if (widget.signViewModel.isSigning) {
160 signFormKey.currentState!.signatureController.text = state.payload as String;
161 } else {
162 WidgetsBinding.instance.addPostFrameCallback((_) {
163 showPopUp<void>(
164 context: context,
165 builder: (_context) {
166 return AlertWithOneAction(
167 alertTitle: S.current.successful,
168 alertContent: S.current.message_verified,
169 buttonText: S.of(_context).ok,
170 buttonAction: () {
171 if (_context.mounted) Navigator.of(_context).pop();
172 },
173 );
174 });
175 });
176 }
177 }
178 });
179 }
180
181 Future<void> _confirmForm(BuildContext context) async {
182 FocusManager.instance.primaryFocus?.unfocus();
183
184 if (widget.signViewModel.isSigning) {
185 String message = signFormKey.currentState!.messageController.text;
186 String? address;
187 if (widget.signViewModel.signIncludesAddress) {
188 address = signFormKey.currentState!.addressController.text;
189 }
190 await widget.signViewModel.sign(message, address: address);
191 } else {
192 String message = verifyFormKey.currentState!.messageController.text;
193 String signature = verifyFormKey.currentState!.signatureController.text;
194 String address = verifyFormKey.currentState!.addressController.text;
195 await widget.signViewModel.verify(message, signature, address: address);
196 }
197 }
198 }