dev
dart 324 lines 11.8 KB
Raw
1 import 'dart:math';
2
3 import 'package:cake_wallet/di.dart';
4 import 'package:cake_wallet/generated/i18n.dart';
5 import 'package:cake_wallet/new-ui/viewmodels/lightning_username/lightning_username_bloc.dart';
6 import 'package:cake_wallet/new-ui/widgets/new_primary_button.dart';
7 import 'package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart';
8 import 'package:cake_wallet/src/widgets/cake_image_widget.dart';
9 import 'package:cake_wallet/themes/core/theme_store.dart';
10 import 'package:cw_core/generate_name.dart';
11 import 'package:flutter/material.dart';
12 import 'package:flutter_bloc/flutter_bloc.dart';
13 import 'package:flutter_svg/flutter_svg.dart';
14
15 class LightningUsernamePage extends StatefulWidget {
16 LightningUsernamePage(
17 {super.key,
18 required this.isSetup,
19 required this.themeStore,
20 required this.lightningUsernameBloc});
21
22 final bool isSetup;
23
24 final ThemeStore themeStore;
25 late final bool isLightMode = !(themeStore.currentTheme.isDark);
26 final LightningUsernameBloc lightningUsernameBloc;
27
28 @override
29 State<LightningUsernamePage> createState() => _LightningUsernamePageState();
30 }
31
32 class _LightningUsernamePageState extends State<LightningUsernamePage> {
33 late bool _editMode;
34 final TextEditingController _controller = TextEditingController();
35
36 @override
37 void initState() {
38 super.initState();
39 _editMode = widget.isSetup;
40 }
41
42 @override
43 Widget build(BuildContext context) {
44 return BlocProvider(
45 create: (context) => widget.lightningUsernameBloc,
46 child: BlocConsumer<LightningUsernameBloc, LightningUsernameState>(
47 listener: (context, state) {
48 if (state is LightningUsernameSaved) {
49 if (widget.isSetup) {
50 Navigator.of(context).popUntil((route) => route.isFirst);
51 } else {
52 Navigator.of(context).pop();
53 }
54 }
55 if (state is LightningUsernameInitial) {
56 if (!widget.isSetup) {
57 _controller.text = state.username;
58 }
59 }
60 },
61 builder: (context, state) {
62 return Material(
63 child: Container(
64 decoration: BoxDecoration(color: Theme.of(context).colorScheme.surface),
65 child: SafeArea(
66 child: Column(
67 children: [
68 ModalTopBar(
69 title: "Lightning ${S.of(context).username}",
70 leadingIcon: Icon(Icons.arrow_back_ios_new),
71 leadingSemanticLabel: S.of(context).seed_alert_back,
72 onLeadingPressed: Navigator.of(context).pop,
73 ),
74 Expanded(
75 child: Column(
76 spacing: 24,
77 mainAxisSize: MainAxisSize.max,
78 mainAxisAlignment: MainAxisAlignment.center,
79 children: [
80 AnimatedSwitcher(
81 duration: const Duration(milliseconds: 200),
82 child: _editMode
83 ? LightningUsernameEditor(
84 isSetup: widget.isSetup,
85 controller: _controller,
86 isLightMode: widget.isLightMode,
87 onRandomizeButtonTap: () {
88 randomizeUsername(context);
89 },
90 state: state,
91 )
92 : LightningUsernameInfo(
93 username: state.username,
94 isLightMode: widget.isLightMode,
95 ),
96 )
97 ],
98 ),
99 ),
100 Padding(
101 padding: const EdgeInsets.symmetric(horizontal: 16.0),
102 child: Column(
103 spacing: 12,
104 children: [
105 if (widget.isSetup) ...[
106 Text(
107 S.of(context).lightning_username_setup_later,
108 textAlign: TextAlign.center,
109 style: TextStyle(
110 fontSize: 12,
111 color: Theme.of(context).colorScheme.onSurfaceVariant),
112 ),
113 SizedBox(),
114 NewPrimaryButton(
115 onPressed: () {
116 Navigator.of(context).popUntil((route) => route.isFirst);
117 },
118 text: S.of(context).skip,
119 color: Theme.of(context).colorScheme.surfaceContainer,
120 textColor: Theme.of(context).colorScheme.primary),
121 ],
122 NewPrimaryButton(
123 onPressed: () {
124 if (_editMode) {
125 context.read<LightningUsernameBloc>().add(RequestUsernameSave());
126 } else {
127 setState(() {
128 _editMode = true;
129 });
130 }
131 },
132 text: _editMode ? S.of(context).confirm : S.of(context).change_username,
133 color: Theme.of(context).colorScheme.primary,
134 textColor: Theme.of(context).colorScheme.onPrimary,
135 disabled: _editMode && (!(state is LightningUsernameReady)),
136 isLoading: (state is LightningUsernameSaving),
137 ),
138 SizedBox()
139 ],
140 ),
141 )
142 ],
143 ),
144 ),
145 ),
146 );
147 },
148 ),
149 );
150 }
151
152 void randomizeUsername(BuildContext context) async {
153 final randomNumber = Random.secure().nextInt(9999);
154 final randomName = await generateName();
155 final username = "${randomName.replaceAll(" ", "")}$randomNumber".toLowerCase();
156
157 context.read<LightningUsernameBloc>().add(ChangeUsername(username));
158 _controller.text = username;
159 }
160 }
161
162 class LightningUsernameInfo extends StatelessWidget {
163 const LightningUsernameInfo({super.key, required this.username, required this.isLightMode});
164
165 final String username;
166 final bool isLightMode;
167
168 @override
169 Widget build(BuildContext context) {
170 return Column(
171 spacing: 24,
172 children: [
173 CakeImageWidget(
174 imageUrl: isLightMode
175 ? "assets/new-ui/lightning_username_setup_light.svg"
176 : "assets/new-ui/lightning_username_setup.svg"),
177 Row(
178 mainAxisAlignment: MainAxisAlignment.center,
179 spacing: 2,
180 children: [
181 Text(
182 username,
183 style: TextStyle(fontSize: 20, fontWeight: FontWeight.w500),
184 ),
185 Text(
186 usernameSuffix,
187 style: TextStyle(
188 fontSize: 20,
189 fontWeight: FontWeight.w500,
190 color: Theme.of(context).colorScheme.primary),
191 textAlign: TextAlign.center,
192 )
193 ],
194 ),
195 Padding(
196 padding: const EdgeInsets.symmetric(horizontal: 32.0),
197 child: Text(
198 S.of(context).lightning_username_desc_completed,
199 style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant),
200 textAlign: TextAlign.center,
201 ),
202 )
203 ],
204 );
205 }
206 }
207
208 class LightningUsernameEditor extends StatelessWidget {
209 const LightningUsernameEditor(
210 {super.key,
211 required this.controller,
212 required this.onRandomizeButtonTap,
213 required this.state,
214 required this.isSetup,
215 required this.isLightMode});
216
217 final TextEditingController controller;
218 final VoidCallback onRandomizeButtonTap;
219 final bool isLightMode;
220 final bool isSetup;
221 final LightningUsernameState state;
222
223 @override
224 Widget build(BuildContext context) {
225 return Column(
226 mainAxisSize: MainAxisSize.min,
227 spacing: 12,
228 children: [
229 CakeImageWidget(
230 imageUrl: isLightMode
231 ? "assets/new-ui/lightning_username_setup_light.svg"
232 : "assets/new-ui/lightning_username_setup.svg"),
233 if (isSetup)
234 Padding(
235 padding: const EdgeInsets.symmetric(horizontal: 18.0),
236 child: Text(
237 S.of(context).lightning_username_desc,
238 textAlign: TextAlign.center,
239 ),
240 ),
241 SizedBox(),
242 Padding(
243 padding: EdgeInsets.symmetric(horizontal: 16),
244 child: Row(
245 children: [
246 Expanded(
247 child: Container(
248 decoration: BoxDecoration(
249 color: Theme.of(context).colorScheme.surfaceContainer,
250 borderRadius: BorderRadius.horizontal(left: Radius.circular(16))),
251 child: Row(
252 spacing: 8,
253 children: [
254 Expanded(
255 child: TextField(
256 onChanged: (val) {
257 context.read<LightningUsernameBloc>().add(ChangeUsername(val));
258 },
259 controller: controller,
260 )),
261 Material(
262 color: Colors.transparent,
263 child: InkWell(
264 onTap: onRandomizeButtonTap,
265 child: CakeImageWidget(
266 imageUrl: "assets/new-ui/randomize.svg",
267 colorFilter: ColorFilter.mode(
268 Theme.of(context).colorScheme.primary, BlendMode.srcIn)),
269 ),
270 ),
271 SizedBox()
272 ],
273 ),
274 ),
275 ),
276 Container(
277 alignment: Alignment.center,
278 height: 56,
279 decoration: BoxDecoration(
280 color: Theme.of(context).colorScheme.surfaceContainerHigh,
281 borderRadius: BorderRadius.horizontal(right: Radius.circular(16))),
282 child: Padding(
283 padding: const EdgeInsets.symmetric(horizontal: 16.0),
284 child: Text(
285 usernameSuffix,
286 style: TextStyle(fontSize: 16),
287 ),
288 ),
289 )
290 ],
291 ),
292 ),
293 if (state is LightningUsernameError)
294 Text(
295 (state as LightningUsernameError).error.message,
296 textAlign: TextAlign.center,
297 style: TextStyle(
298 color: (state as LightningUsernameError).error.isInfo
299 ? Colors.green
300 : Theme.of(context).colorScheme.error),
301 )
302 else if (state is LightningUsernameReady)
303 Row(
304 mainAxisAlignment: MainAxisAlignment.center,
305 spacing: 8,
306 children: [
307 Icon(
308 Icons.check,
309 color: Colors.green,
310 size: 12,
311 ),
312 Text(
313 S.of(context).username_available,
314 style: TextStyle(color: Colors.green),
315 )
316 ],
317 )
318 else
319 Text(""),
320 SizedBox(height: MediaQuery.of(context).viewInsets.bottom.clamp(0, 100))
321 ],
322 );
323 }
324 }