dev
dart 258 lines 12.2 KB
Raw
1 import 'package:cake_wallet/entities/bitcoin_amount_display_mode.dart';
2 import 'package:cake_wallet/entities/language_service.dart';
3 import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item_regular_row.dart';
4 import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item_selector.dart';
5 import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item_toggle.dart';
6 import 'package:cake_wallet/entities/sync_status_display_mode.dart';
7 import 'package:cake_wallet/generated/i18n.dart';
8 import 'package:cake_wallet/new-ui/widgets/currency_picker/fiat_currency_picker_sheet.dart';
9 import 'package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart';
10 import 'package:cake_wallet/src/screens/settings/widgets/settings_choices_cell.dart';
11 import 'package:cake_wallet/src/screens/settings/widgets/settings_theme_choice.dart';
12 import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
13 import 'package:cake_wallet/src/widgets/new_list_row/new_list_section.dart';
14 import 'package:cake_wallet/new-ui/widgets/modal_page_wrapper.dart';
15 import 'package:cake_wallet/src/widgets/picker.dart';
16 import 'package:cake_wallet/src/widgets/standard_list.dart';
17 import 'package:cake_wallet/utils/device_info.dart';
18 import 'package:cake_wallet/utils/feature_flag.dart';
19 import 'package:cake_wallet/utils/responsive_layout_util.dart';
20 import 'package:cake_wallet/utils/show_pop_up.dart';
21 import 'package:cake_wallet/view_model/settings/choices_list_item.dart';
22 import 'package:cake_wallet/view_model/settings/display_settings_view_model.dart';
23 import 'package:flutter/material.dart';
24 import 'package:flutter_mobx/flutter_mobx.dart';
25 import 'package:image_picker/image_picker.dart';
26
27 class DisplaySettingsPage extends StatelessWidget {
28 DisplaySettingsPage(this._displaySettingsViewModel);
29
30 final DisplaySettingsViewModel _displaySettingsViewModel;
31
32 @override
33 Widget build(BuildContext context) {
34 return ModalPageWrapper(
35 topBar: ModalTopBar(
36 title: S.of(context).display,
37 leadingIcon: Icon(Icons.arrow_back_ios_new),
38 leadingSemanticLabel: S.of(context).seed_alert_back,
39 onLeadingPressed: () => Navigator.of(context).pop(),
40 ),
41 content: Column(
42 spacing: 16,
43 crossAxisAlignment: CrossAxisAlignment.start,
44 children: [
45 if (responsiveLayoutUtil.shouldRenderMobileUI && DeviceInfo.instance.isMobile) ...[
46 Padding(
47 padding: const EdgeInsets.only(left: 14, top: 14),
48 child: Text(
49 S.of(context).appearance,
50 style: Theme.of(context).textTheme.labelLarge?.copyWith(
51 height: 0.2,
52 color: Theme.of(context).colorScheme.onSurfaceVariant,
53 ),
54 ),
55 ),
56 Container(
57 decoration: ShapeDecoration(
58 color: Theme.of(context).colorScheme.surfaceContainerHigh,
59 shape: RoundedSuperellipseBorder(borderRadius: BorderRadius.circular(18))),
60 child: Column(
61 children: [
62 SettingsChoicesCell(
63 ChoicesListItem<ThemeMode>(
64 title: "",
65 items: ThemeMode.values,
66 selectedItem: _displaySettingsViewModel.themeMode,
67 onItemSelected: (ThemeMode themeMode) =>
68 _displaySettingsViewModel.setThemeMode(themeMode),
69 displayItem: (ThemeMode themeMode) {
70 return themeMode.name[0].toUpperCase() +
71 themeMode.name.substring(1).toLowerCase();
72 },
73 ),
74 useGenericColor: false,
75 padding: EdgeInsets.all(14),
76 ),
77 Container(
78 decoration: ShapeDecoration(
79 color: Theme.of(context).colorScheme.surfaceContainer,
80 shape: RoundedSuperellipseBorder(borderRadius: BorderRadius.circular(18))),
81 child: Column(
82 children: [
83 Semantics(
84 label: S.of(context).color_theme,
85 child: SettingsThemeChoicesCell(_displaySettingsViewModel),
86 ),
87 ],
88 ),
89 ),
90 ],
91 ),
92 ),
93 ],
94 Observer(
95 builder: (_) => NewListSections(
96 sections: {
97 "": [
98 ListItemToggle(
99 keyValue: "apps",
100 label: S.of(context).apps,
101 value: _displaySettingsViewModel.shouldShowMarketPlaceInDashboard,
102 onChanged: (val) {
103 _displaySettingsViewModel.setShouldShowMarketPlaceInDashbaord(val);
104 }),
105 ListItemToggle(
106 keyValue: "display_settings_show_address_book_popup",
107 label: S.of(context).show_address_book_popup,
108 value: _displaySettingsViewModel.showAddressBookPopup,
109 onChanged: (val) {
110 _displaySettingsViewModel.setShowAddressBookPopup(val);
111 }),
112 ListItemToggle(
113 keyValue: "display_settings_disable_buy_button",
114 label: S.of(context).disable_buy,
115 value: _displaySettingsViewModel.disableTradeOption,
116 onChanged: (val) {
117 _displaySettingsViewModel.setDisableTradeOption(val);
118 }),
119 ListItemSelector(
120 keyValue: "display_settings_sync_status_display",
121 label: S.of(context).sync_status_display_mode,
122 options: [_displaySettingsViewModel.syncStatusDisplayMode.title],
123 onTap: () async {
124 final items = SyncStatusDisplayMode.values.toList();
125 final selectedAtIndex =
126 items.indexOf(_displaySettingsViewModel.syncStatusDisplayMode);
127
128 await showPopUp<void>(
129 context: context,
130 builder: (_) => Picker(
131 items: items,
132 selectedAtIndex: selectedAtIndex,
133 mainAxisAlignment: MainAxisAlignment.start,
134 onItemSelected: (SyncStatusDisplayMode mode) {
135 _displaySettingsViewModel.setSyncStatusDisplayMode(mode);
136 },
137 displayItem: (SyncStatusDisplayMode mode) => mode.title,
138 isSeparated: false,
139 ),
140 );
141 }),
142 if (_displaySettingsViewModel.showDisplayAmountsInSatoshiSetting)
143 ListItemRegularRow(
144 keyValue: "display_settings_bitcoin_amount_display",
145 label: S.of(context).bitcoin_amount_display,
146 trailingText: _displaySettingsViewModel.displayAmountsInSatoshi.title,
147 onTap: () async {
148 final items = BitcoinAmountDisplayMode.all;
149
150 final selectedAtIndex =
151 items.indexOf(_displaySettingsViewModel.displayAmountsInSatoshi);
152
153 await showPopUp<void>(
154 context: context,
155 builder: (_) => Picker(
156 items: items,
157 selectedAtIndex: selectedAtIndex,
158 mainAxisAlignment: MainAxisAlignment.start,
159 onItemSelected: _displaySettingsViewModel.setDisplayAmountsInSatoshi,
160 displayItem: (BitcoinAmountDisplayMode mode) => mode.title,
161 isSeparated: false,
162 ),
163 );
164 }),
165 if (!_displaySettingsViewModel.disabledFiatApiMode)
166 ListItemSelector(
167 keyValue: "display_settings_fiat_currency",
168 label: S.of(context).settings_currency,
169 options: [_displaySettingsViewModel.fiatCurrency.title],
170 onTap: () => FiatCurrencyPickerSheet.show(
171 context: context,
172 selected: _displaySettingsViewModel.fiatCurrency,
173 onSelected: _displaySettingsViewModel.setFiatCurrency,
174 )),
175 ListItemSelector(
176 keyValue: "display_settings_language",
177 label: S.of(context).settings_change_language,
178 options: [LanguageService.list[_displaySettingsViewModel.languageCode] ?? ''],
179 onTap: () async {
180 final items = LanguageService.list.keys.toList();
181
182 final selectedAtIndex =
183 items.indexOf(_displaySettingsViewModel.languageCode);
184
185 await showPopUp<void>(
186 context: context,
187 builder: (_) => Picker(
188 displayItem: (dynamic code) {
189 return LanguageService.list[code] ?? '';
190 },
191 items: items,
192 selectedAtIndex: selectedAtIndex,
193 mainAxisAlignment: MainAxisAlignment.start,
194 onItemSelected: _displaySettingsViewModel.onLanguageSelected,
195 images: LanguageService.list.keys
196 .map((e) => Image.asset(
197 "assets/images/flags/${LanguageService.localeCountryCode[e]}.png"))
198 .toList(),
199 hintText: S.of(context).search_language,
200 matchingCriteria: (String code, String searchText) {
201 return LanguageService.list[code]
202 ?.toLowerCase()
203 .contains(searchText) ??
204 false;
205 },
206 isSeparated: true,
207 ),
208 );
209 }),
210 ],
211 },
212 ),
213 ),
214 if (FeatureFlag.customBackgroundEnabled)
215 StandardListRow(
216 title: "Custom background",
217 isSelected: false,
218 onTap: (_) => _pickImage(context),
219 ),
220 ],
221 ),
222 );
223 }
224
225 // Function to pick an image from the gallery
226 Future<void> _pickImage(BuildContext context) async {
227 if (_displaySettingsViewModel.backgroundImage.isNotEmpty) {
228 final bool? shouldReplace = await showPopUp<bool>(
229 context: context,
230 builder: (BuildContext context) {
231 return AlertWithTwoActions(
232 alertTitle: S.of(context).replace,
233 alertContent: S.of(context).customBackgroundDescription,
234 rightButtonText: S.of(context).replace,
235 leftButtonText: S.of(context).remove,
236 actionRightButton: () => Navigator.of(context).pop(true),
237 actionLeftButton: () => Navigator.of(context).pop(false));
238 });
239
240 if (shouldReplace == false) {
241 // remove the current background by setting it as an empty string
242 _displaySettingsViewModel.setBackgroundImage("");
243 return;
244 } else if (shouldReplace == null) {
245 // user didn't choose anything, then just return
246 return;
247 }
248 }
249
250 final ImagePicker picker = ImagePicker();
251 // Pick an image from the gallery
252 final XFile? pickedFile = await picker.pickImage(source: ImageSource.gallery);
253
254 if (pickedFile != null) {
255 _displaySettingsViewModel.setBackgroundImage(pickedFile.path);
256 }
257 }
258 }