dev
dart 195 lines 5.97 KB
Raw
1 import 'package:cake_wallet/core/selectable_option.dart';
2 import 'package:cake_wallet/src/screens/base_page.dart';
3 import 'package:cake_wallet/src/widgets/primary_button.dart';
4 import 'package:cake_wallet/src/widgets/provider_optoin_tile.dart';
5 import 'package:cake_wallet/src/widgets/scrollable_with_bottom_section.dart';
6 import 'package:cake_wallet/themes/core/material_base_theme.dart';
7 import 'package:flutter/material.dart';
8
9 abstract class SelectOptionsPage extends BasePage {
10 SelectOptionsPage();
11
12 String get pageTitle;
13
14 EdgeInsets? get contentPadding;
15
16 EdgeInsets? get tilePadding;
17
18 EdgeInsets? get innerPadding;
19
20 double? get imageHeight;
21
22 double? get imageWidth;
23
24 Color? get selectedBackgroundColor;
25
26 double? get tileBorderRadius;
27
28 String get bottomSectionText;
29
30 bool get primaryButtonEnabled => true;
31
32 String get primaryButtonText => '';
33
34 List<SelectableItem> get items;
35
36 void Function(SelectableOption option)? get onOptionTap;
37
38 void Function(BuildContext context)? get primaryButtonAction;
39
40 @override
41 String get title => pageTitle;
42
43 @override
44 Widget body(BuildContext context) {
45 return ScrollableWithBottomSection(
46 content: BodySelectOptionsPage(
47 currentTheme: currentTheme,
48 items: items,
49 onOptionTap: onOptionTap,
50 tilePadding: tilePadding,
51 tileBorderRadius: tileBorderRadius,
52 imageHeight: imageHeight,
53 imageWidth: imageWidth,
54 innerPadding: innerPadding,
55 ),
56 bottomSection: Padding(
57 padding: contentPadding ?? EdgeInsets.zero,
58 child: Column(
59 children: [
60 Text(
61 bottomSectionText,
62 textAlign: TextAlign.center,
63 style: Theme.of(context).textTheme.bodyMedium!.copyWith(
64 color: Theme.of(context).colorScheme.onSurfaceVariant,
65 ),
66 ),
67 if (primaryButtonEnabled)
68 LoadingPrimaryButton(
69 text: primaryButtonText,
70 onPressed: () {
71 primaryButtonAction != null
72 ? primaryButtonAction!(context)
73 : Navigator.pop(context);
74 },
75 color: Theme.of(context).colorScheme.primary,
76 textColor: Theme.of(context).colorScheme.onPrimary,
77 isDisabled: false,
78 isLoading: false,
79 )
80 ],
81 ),
82 ),
83 );
84 }
85 }
86
87 class BodySelectOptionsPage extends StatefulWidget {
88 const BodySelectOptionsPage({
89 required this.items,
90 this.onOptionTap,
91 this.tilePadding,
92 this.tileBorderRadius,
93 this.imageHeight,
94 this.imageWidth,
95 this.innerPadding,
96 required this.currentTheme,
97 });
98
99 final List<SelectableItem> items;
100 final void Function(SelectableOption option)? onOptionTap;
101 final EdgeInsets? tilePadding;
102 final double? tileBorderRadius;
103 final double? imageHeight;
104 final double? imageWidth;
105 final EdgeInsets? innerPadding;
106 final MaterialThemeBase currentTheme;
107
108 @override
109 _BodySelectOptionsPageState createState() => _BodySelectOptionsPageState();
110 }
111
112 class _BodySelectOptionsPageState extends State<BodySelectOptionsPage> {
113 late List<SelectableItem> _items;
114
115 @override
116 void initState() {
117 super.initState();
118 _items = widget.items;
119 }
120
121 void _handleOptionTap(SelectableOption option) {
122 setState(() {
123 for (var item in _items) {
124 if (item is SelectableOption) {
125 item.isOptionSelected = false;
126 }
127 }
128 option.isOptionSelected = true;
129 });
130 widget.onOptionTap?.call(option);
131 }
132
133 @override
134 Widget build(BuildContext context) {
135 return Center(
136 child: ConstrainedBox(
137 constraints: const BoxConstraints(maxWidth: 350),
138 child: Column(
139 children: _items.map((item) {
140 if (item is OptionTitle) {
141 return Padding(
142 padding: const EdgeInsets.only(top: 18, bottom: 8),
143 child: Container(
144 width: double.infinity,
145 decoration: BoxDecoration(
146 border: Border(
147 bottom: BorderSide(
148 color: Theme.of(context).colorScheme.onSurface,
149 width: 1,
150 ),
151 ),
152 ),
153 child: Padding(
154 padding: const EdgeInsets.only(bottom: 8.0),
155 child: Text(
156 item.title,
157 style: Theme.of(context).textTheme.bodyMedium!.copyWith(
158 fontSize: 18,
159 fontWeight: FontWeight.w700,
160 ),
161 ),
162 ),
163 ),
164 );
165 } else if (item is SelectableOption) {
166 return Padding(
167 padding: widget.tilePadding ?? const EdgeInsets.only(top: 24),
168 child: ProviderOptionTile(
169 title: item.title,
170 lightImagePath: item.lightIconPath,
171 darkImagePath: item.darkIconPath,
172 imageHeight: widget.imageHeight,
173 imageWidth: widget.imageWidth,
174 padding: widget.innerPadding,
175 description: item.description,
176 topLeftSubTitle: item.topLeftSubTitle,
177 topRightSubTitle: item.topRightSubTitle,
178 rightSubTitleLightIconPath: item.topRightSubTitleLightIconPath,
179 rightSubTitleDarkIconPath: item.topRightSubTitleDarkIconPath,
180 bottomLeftSubTitle: item.bottomLeftSubTitle,
181 badges: item.badges,
182 isSelected: item.isOptionSelected,
183 borderRadius: widget.tileBorderRadius,
184 isLightMode: widget.currentTheme.isDark,
185 onPressed: () => _handleOptionTap(item),
186 ),
187 );
188 }
189 return const SizedBox.shrink();
190 }).toList(),
191 ),
192 ),
193 );
194 }
195 }