Reorganize settings

Godwin Asuquo committed Nov 16, 2022 at 09:29 UTC 549975ecc17316141ab22b20892fd5d7fe24140a
28 files changed +619 -373
lib/di.dart
+15 -3
@@ -5,9 +5,14 @@ import 'package:cake_wallet/ionia/ionia_anypay.dart';
5 import 'package:cake_wallet/ionia/ionia_gift_card.dart';
6 import 'package:cake_wallet/ionia/ionia_tip.dart';
7 import 'package:cake_wallet/src/screens/buy/onramper_page.dart';
8 +import 'package:cake_wallet/src/screens/setting/display_settings_page.dart';
9 +import 'package:cake_wallet/src/screens/setting/other_settings_page.dart';
10 +import 'package:cake_wallet/src/screens/setting/privacy_page.dart';
11 +import 'package:cake_wallet/src/screens/setting/security_backup_page.dart';
12 import 'package:cake_wallet/src/screens/ionia/cards/ionia_custom_redeem_page.dart';
13 import 'package:cake_wallet/src/screens/ionia/cards/ionia_gift_card_detail_page.dart';
14 import 'package:cake_wallet/src/screens/ionia/cards/ionia_more_options_page.dart';
15 +import 'package:cake_wallet/src/screens/settings/connection_sync_page.dart';
16 import 'package:cake_wallet/view_model/ionia/ionia_auth_view_model.dart';
17 import 'package:cake_wallet/view_model/ionia/ionia_buy_card_view_model.dart';
18 import 'package:cake_wallet/view_model/ionia/ionia_custom_tip_view_model.dart';
@@ -59,7 +64,6 @@ import 'package:cake_wallet/src/screens/restore/wallet_restore_page.dart';
64 import 'package:cake_wallet/src/screens/seed/pre_seed_page.dart';
65 import 'package:cake_wallet/src/screens/seed/wallet_seed_page.dart';
66 import 'package:cake_wallet/src/screens/send/send_template_page.dart';
62 -import 'package:cake_wallet/src/screens/settings/settings.dart';
67 import 'package:cake_wallet/src/screens/setup_pin_code/setup_pin_code.dart';
68 import 'package:cake_wallet/src/screens/support/support_page.dart';
69 import 'package:cake_wallet/src/screens/trade_details/trade_details_page.dart';
@@ -439,8 +443,6 @@ Future setup(
443 return SettingsViewModel(appStore.settingsStore, yatStore, appStore.wallet!);
444 });
445
442 - getIt.registerFactory(() => SettingsPage(getIt.get<SettingsViewModel>()));
443 -
446 getIt
447 .registerFactory(() => WalletSeedViewModel(getIt.get<AppStore>().wallet!));
448
@@ -477,6 +479,16 @@ Future setup(
479
480 getIt.registerFactory(() => NodeListPage(getIt.get<NodeListViewModel>()));
481
482 + getIt.registerFactory(() => ConnectionSyncPage(getIt.get<NodeListViewModel>(), getIt.get<DashboardViewModel>()));
483 +
484 + getIt.registerFactory(() => SecurityBackupPage(getIt.get<SettingsViewModel>()));
485 +
486 + getIt.registerFactory(() => PrivacyPage(getIt.get<SettingsViewModel>()));
487 +
488 + getIt.registerFactory(() => DisplaySettingsPage(getIt.get<SettingsViewModel>()));
489 +
490 + getIt.registerFactory(() => OtherSettingsPage(getIt.get<SettingsViewModel>()));
491 +
492 getIt.registerFactory(() =>
493 NodeCreateOrEditViewModel(_nodeSource, getIt.get<AppStore>().wallet!));
494
lib/router.dart
+25 -4
@@ -5,6 +5,10 @@ import 'package:cake_wallet/src/screens/backup/edit_backup_password_page.dart';
5 import 'package:cake_wallet/src/screens/buy/buy_webview_page.dart';
6 import 'package:cake_wallet/src/screens/buy/onramper_page.dart';
7 import 'package:cake_wallet/src/screens/buy/pre_order_page.dart';
8 +import 'package:cake_wallet/src/screens/setting/display_settings_page.dart';
9 +import 'package:cake_wallet/src/screens/setting/other_settings_page.dart';
10 +import 'package:cake_wallet/src/screens/setting/privacy_page.dart';
11 +import 'package:cake_wallet/src/screens/setting/security_backup_page.dart';
12 import 'package:cake_wallet/src/screens/ionia/cards/ionia_account_cards_page.dart';
13 import 'package:cake_wallet/src/screens/ionia/cards/ionia_account_page.dart';
14 import 'package:cake_wallet/src/screens/ionia/cards/ionia_custom_redeem_page.dart';
@@ -16,6 +20,7 @@ import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
20 import 'package:cake_wallet/src/screens/restore/restore_from_backup_page.dart';
21 import 'package:cake_wallet/src/screens/restore/wallet_restore_page.dart';
22 import 'package:cake_wallet/src/screens/seed/pre_seed_page.dart';
23 +import 'package:cake_wallet/src/screens/settings/connection_sync_page.dart';
24 import 'package:cake_wallet/src/screens/support/support_page.dart';
25 import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_details_page.dart';
26 import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_list_page.dart';
@@ -56,7 +61,6 @@ import 'package:cake_wallet/src/screens/contact/contact_page.dart';
61 import 'package:cake_wallet/src/screens/wallet_keys/wallet_keys_page.dart';
62 import 'package:cake_wallet/src/screens/restore/restore_wallet_from_seed_details.dart';
63 import 'package:cake_wallet/src/screens/exchange/exchange_page.dart';
59 -import 'package:cake_wallet/src/screens/settings/settings.dart';
64 import 'package:cake_wallet/src/screens/rescan/rescan_page.dart';
65 import 'package:cake_wallet/src/screens/faq/faq_page.dart';
66 import 'package:cake_wallet/src/screens/trade_details/trade_details_page.dart';
@@ -278,6 +282,26 @@ Route<dynamic> createRoute(RouteSettings settings) {
282 return CupertinoPageRoute<void>(
283 builder: (_) => getIt.get<NodeListPage>());
284
285 + case Routes.connectionSync:
286 + return CupertinoPageRoute<void>(
287 + builder: (_) => getIt.get<ConnectionSyncPage>());
288 +
289 + case Routes.securityBackupPage:
290 + return CupertinoPageRoute<void>(
291 + builder: (_) => getIt.get<SecurityBackupPage>());
292 +
293 + case Routes.privacyPage:
294 + return CupertinoPageRoute<void>(
295 + builder: (_) => getIt.get<PrivacyPage>());
296 +
297 + case Routes.displaySettingsPage:
298 + return CupertinoPageRoute<void>(
299 + builder: (_) => getIt.get<DisplaySettingsPage>());
300 +
301 + case Routes.otherSettingsPage:
302 + return CupertinoPageRoute<void>(
303 + builder: (_) => getIt.get<OtherSettingsPage>());
304 +
305 case Routes.newNode:
306 return CupertinoPageRoute<void>(
307 builder: (_) => getIt.get<NodeCreateOrEditPage>());
@@ -360,9 +384,6 @@ Route<dynamic> createRoute(RouteSettings settings) {
384 return CupertinoPageRoute<void>(
385 builder: (_) => getIt.get<ExchangeTemplatePage>());
386
363 - case Routes.settings:
364 - return MaterialPageRoute<void>(builder: (_) => getIt.get<SettingsPage>());
365 -
387 case Routes.rescan:
388 return MaterialPageRoute<void>(builder: (_) => getIt.get<RescanPage>());
389
lib/routes.dart
+5
@@ -77,4 +77,9 @@ class Routes {
77 static const ioniaMoreOptionsPage = '/ionia_more_options_page';
78 static const ioniaCustomRedeemPage = '/ionia_custom_redeem_page';
79 static const onramperPage = '/onramper';
80 + static const connectionSync = '/connection_sync_page';
81 + static const securityBackupPage = '/security_and_backup_page';
82 + static const privacyPage = '/privacy_page';
83 + static const displaySettingsPage = '/display_settings_page';
84 + static const otherSettingsPage = '/other_settings_page';
85 }
lib/src/screens/dashboard/wallet_menu.dart
+51 -85
@@ -1,81 +1,64 @@
1 import 'package:cake_wallet/palette.dart';
2 import 'package:cake_wallet/src/screens/dashboard/wallet_menu_item.dart';
3 -import 'package:cake_wallet/utils/show_pop_up.dart';
3 import 'package:flutter/material.dart';
4 import 'package:cake_wallet/routes.dart';
5 import 'package:cake_wallet/generated/i18n.dart';
7 -import 'package:cake_wallet/src/screens/auth/auth_page.dart';
8 -import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
9 -import 'package:cake_wallet/wallet_type_utils.dart';
6
7 // FIXME: terrible design
8
9 class WalletMenu {
10 WalletMenu(this.context, this.reconnect, this.hasRescan) : items = [] {
11 items.addAll([
16 - WalletMenuItem(
17 - title: S.current.reconnect,
18 - image: Image.asset('assets/images/reconnect_menu.png',
19 - height: 16, width: 16),
20 - handler: () => _presentReconnectAlert(context)),
21 - if (hasRescan)
22 - WalletMenuItem(
23 - title: S.current.rescan,
24 - image: Image.asset('assets/images/filter_icon.png',
25 - height: 16, width: 16, color: Palette.darkBlue),
26 - handler: () => Navigator.of(context).pushNamed(Routes.rescan)),
27 - WalletMenuItem(
28 - title: S.current.wallets,
29 - image: Image.asset('assets/images/wallet_menu.png',
30 - height: 16, width: 16),
31 - handler: () => Navigator.of(context).pushNamed(Routes.walletList)),
32 - WalletMenuItem(
33 - title: S.current.nodes,
34 - image: Image.asset('assets/images/nodes_menu.png',
35 - height: 16, width: 16),
36 - handler: () => Navigator.of(context).pushNamed(Routes.nodeList)),
37 - WalletMenuItem(
38 - title: S.current.show_keys,
39 - image:
40 - Image.asset('assets/images/key_menu.png', height: 16, width: 16),
41 - handler: () {
42 - Navigator.of(context).pushNamed(Routes.auth,
43 - arguments: (bool isAuthenticatedSuccessfully, AuthPageState auth) {
44 - if (isAuthenticatedSuccessfully) {
45 - auth.close(route: Routes.showKeys);
46 - }
47 - });
48 - }),
49 - WalletMenuItem(
50 - title: S.current.address_book_menu,
51 - image: Image.asset('assets/images/open_book_menu.png',
52 - height: 16, width: 16),
53 - handler: () => Navigator.of(context).pushNamed(Routes.addressBook)),
54 - WalletMenuItem(
55 - title: S.current.backup,
56 - image: Image.asset('assets/images/restore_wallet.png',
57 - height: 16,
58 - width: 16,
59 - color: Palette.darkBlue),
60 - handler: () {
61 - Navigator.of(context).pushNamed(
62 - Routes.auth,
63 - arguments: (bool isAuthenticatedSuccessfully, AuthPageState auth) {
64 - if (isAuthenticatedSuccessfully) {
65 - auth.close(route:Routes.backup);
66 - }
67 - });
68 - }),
69 - WalletMenuItem(
70 - title: S.current.settings_title,
71 - image: Image.asset('assets/images/settings_menu.png',
72 - height: 16, width: 16),
73 - handler: () => Navigator.of(context).pushNamed(Routes.settings)),
74 - WalletMenuItem(
75 - title: S.current.settings_support,
76 - image: Image.asset('assets/images/question_mark.png',
77 - height: 16, width: 16, color: Palette.darkBlue),
78 - handler: () => Navigator.of(context).pushNamed(Routes.support)),
12 + WalletMenuItem(
13 + title: S.current.connection_sync,
14 + image: Image.asset('assets/images/nodes_menu.png',
15 + height: 16, width: 16),
16 + handler: () => Navigator.of(context).pushNamed(Routes.connectionSync),
17 + ),
18 + WalletMenuItem(
19 + title: S.current.wallets,
20 + image: Image.asset('assets/images/wallet_menu.png',
21 + height: 16, width: 16),
22 + handler: () => Navigator.of(context).pushNamed(Routes.walletList),
23 + ),
24 + WalletMenuItem(
25 + title: S.current.security_and_backup,
26 + image:
27 + Image.asset('assets/images/key_menu.png', height: 16, width: 16),
28 + handler: () {
29 + Navigator.of(context).pushNamed(Routes.securityBackupPage);
30 + }),
31 + WalletMenuItem(
32 + title: S.current.privacy,
33 + image:
34 + Image.asset('assets/images/eye_menu.png', height: 16, width: 16),
35 + handler: () {
36 + Navigator.of(context).pushNamed(Routes.privacyPage);
37 + }),
38 + WalletMenuItem(
39 + title: S.current.address_book_menu,
40 + image: Image.asset('assets/images/open_book_menu.png',
41 + height: 16, width: 16),
42 + handler: () => Navigator.of(context).pushNamed(Routes.addressBook),
43 + ),
44 + WalletMenuItem(
45 + title: S.current.display_settings,
46 + image: Image.asset('assets/images/eye_menu.png',
47 + height: 16, width: 16),
48 + handler: () => Navigator.of(context).pushNamed(Routes.displaySettingsPage),
49 + ),
50 + WalletMenuItem(
51 + title: S.current.other_settings,
52 + image: Image.asset('assets/images/settings_menu.png',
53 + height: 16, width: 16),
54 + handler: () => Navigator.of(context).pushNamed(Routes.otherSettingsPage),
55 + ),
56 + WalletMenuItem(
57 + title: S.current.settings_support,
58 + image: Image.asset('assets/images/question_mark.png',
59 + height: 16, width: 16, color: Palette.darkBlue),
60 + handler: () => Navigator.of(context).pushNamed(Routes.support),
61 + ),
62 ]);
63 }
64
@@ -86,23 +69,6 @@ class WalletMenu {
69
70 void action(int index) {
71 final item = items[index];
89 - item?.handler();
90 - }
91 -
92 - Future<void> _presentReconnectAlert(BuildContext context) async {
93 - await showPopUp<void>(
94 - context: context,
95 - builder: (BuildContext context) {
96 - return AlertWithTwoActions(
97 - alertTitle: S.of(context).reconnection,
98 - alertContent: S.of(context).reconnect_alert_text,
99 - rightButtonText: S.of(context).ok,
100 - leftButtonText: S.of(context).cancel,
101 - actionRightButton: () async {
102 - Navigator.of(context).pop();
103 - await reconnect?.call();
104 - },
105 - actionLeftButton: () => Navigator.of(context).pop());
106 - });
72 + item.handler();
73 }
74 }
lib/src/screens/nodes/widgets/node_list_row.dart
+5 -2
@@ -37,7 +37,10 @@ class NodeHeaderListRow extends StandardListRow {
37
38 @override
39 Widget buildTrailing(BuildContext context) {
40 - return Icon(Icons.add,
41 - color: Theme.of(context).accentTextTheme!.subtitle1!.color!, size: 24.0);
40 + return SizedBox(
41 + width: 20,
42 + child: Icon(Icons.add,
43 + color: Theme.of(context).accentTextTheme!.subtitle1!.color!, size: 24.0),
44 + );
45 }
46 }
lib/src/screens/settings/connection_sync_page.dart new
+155
@@ -0,0 +1,155 @@
1 +import 'package:cake_wallet/src/screens/settings/widgets/settings_cell_with_arrow.dart';
2 +import 'package:cake_wallet/utils/show_pop_up.dart';
3 +import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
4 +import 'package:cw_core/node.dart';
5 +import 'package:flutter/material.dart';
6 +import 'package:flutter/cupertino.dart';
7 +import 'package:flutter_mobx/flutter_mobx.dart';
8 +import 'package:cake_wallet/routes.dart';
9 +import 'package:cake_wallet/generated/i18n.dart';
10 +import 'package:cake_wallet/src/screens/base_page.dart';
11 +import 'package:cake_wallet/src/screens/nodes/widgets/node_list_row.dart';
12 +import 'package:cake_wallet/src/widgets/standard_list.dart';
13 +import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
14 +import 'package:cake_wallet/view_model/node_list/node_list_view_model.dart';
15 +import 'package:flutter_slidable/flutter_slidable.dart';
16 +
17 +class ConnectionSyncPage extends BasePage {
18 + ConnectionSyncPage(this.nodeListViewModel, this.dashboardViewModel);
19 +
20 + @override
21 + String get title => S.current.connection_sync;
22 +
23 + final NodeListViewModel nodeListViewModel;
24 + final DashboardViewModel dashboardViewModel;
25 +
26 + @override
27 + Widget body(BuildContext context) {
28 + return Container(
29 + padding: EdgeInsets.only(top: 10),
30 + child: Column(
31 + mainAxisSize: MainAxisSize.min,
32 + children: [
33 + SettingsCellWithArrow(
34 + title: S.current.reconnect,
35 + handler: (context) => _presentReconnectAlert(context),
36 + ),
37 + StandardListSeparator(padding: EdgeInsets.symmetric(horizontal: 24)),
38 + SettingsCellWithArrow(
39 + title: S.current.rescan,
40 + handler: (context) => Navigator.of(context).pushNamed(Routes.rescan),
41 + ),
42 + StandardListSeparator(padding: EdgeInsets.symmetric(horizontal: 24)),
43 + NodeHeaderListRow(
44 + title: S.of(context).add_new_node,
45 + onTap: (_) async => await Navigator.of(context).pushNamed(Routes.newNode),
46 + ),
47 + StandardListSeparator(padding: EdgeInsets.symmetric(horizontal: 24)),
48 + SizedBox(height: 100),
49 + Observer(
50 + builder: (BuildContext context) {
51 + return Flexible(
52 + child: SectionStandardList(
53 + sectionCount: 1,
54 + context: context,
55 + dividerPadding: EdgeInsets.symmetric(horizontal: 24),
56 + itemCounter: (int sectionIndex) {
57 + return nodeListViewModel.nodes.length;
58 + },
59 + itemBuilder: (_, sectionIndex, index) {
60 + final node = nodeListViewModel.nodes[index];
61 + final isSelected = node.keyIndex == nodeListViewModel.currentNode.keyIndex;
62 + final nodeListRow = NodeListRow(
63 + title: node.uriRaw,
64 + isSelected: isSelected,
65 + isAlive: node.requestNode(),
66 + onTap: (_) async {
67 + if (isSelected) {
68 + return;
69 + }
70 +
71 + await showPopUp<void>(
72 + context: context,
73 + builder: (BuildContext context) {
74 + return AlertWithTwoActions(
75 + alertTitle: S.of(context).change_current_node_title,
76 + alertContent: S.of(context).change_current_node(node.uriRaw),
77 + leftButtonText: S.of(context).cancel,
78 + rightButtonText: S.of(context).change,
79 + actionLeftButton: () => Navigator.of(context).pop(),
80 + actionRightButton: () async {
81 + await nodeListViewModel.setAsCurrent(node);
82 + Navigator.of(context).pop();
83 + },
84 + );
85 + });
86 + },
87 + );
88 +
89 + final dismissibleRow = Slidable(
90 + key: Key('${node.keyIndex}'),
91 + startActionPane: _actionPane(context, node),
92 + endActionPane: _actionPane(context, node),
93 + child: nodeListRow,
94 + );
95 +
96 + return isSelected ? nodeListRow : dismissibleRow;
97 + },
98 + ),
99 + );
100 + },
101 + ),
102 + ],
103 + ),
104 + );
105 + }
106 +
107 + Future<void> _presentReconnectAlert(BuildContext context) async {
108 + await showPopUp<void>(
109 + context: context,
110 + builder: (BuildContext context) {
111 + return AlertWithTwoActions(
112 + alertTitle: S.of(context).reconnection,
113 + alertContent: S.of(context).reconnect_alert_text,
114 + rightButtonText: S.of(context).ok,
115 + leftButtonText: S.of(context).cancel,
116 + actionRightButton: () async {
117 + Navigator.of(context).pop();
118 + await dashboardViewModel.reconnect();
119 + },
120 + actionLeftButton: () => Navigator.of(context).pop());
121 + },
122 + );
123 + }
124 +
125 + ActionPane _actionPane(BuildContext context, Node node) => ActionPane(
126 + motion: const ScrollMotion(),
127 + extentRatio: 0.3,
128 + children: [
129 + SlidableAction(
130 + onPressed: (context) async {
131 + final confirmed = await showPopUp<bool>(
132 + context: context,
133 + builder: (BuildContext context) {
134 + return AlertWithTwoActions(
135 + alertTitle: S.of(context).remove_node,
136 + alertContent: S.of(context).remove_node_message,
137 + rightButtonText: S.of(context).remove,
138 + leftButtonText: S.of(context).cancel,
139 + actionRightButton: () => Navigator.pop(context, true),
140 + actionLeftButton: () => Navigator.pop(context, false));
141 + }) ??
142 + false;
143 +
144 + if (confirmed) {
145 + await nodeListViewModel.delete(node);
146 + }
147 + },
148 + backgroundColor: Colors.red,
149 + foregroundColor: Colors.white,
150 + icon: CupertinoIcons.delete,
151 + label: S.of(context).delete,
152 + ),
153 + ],
154 + );
155 +}
lib/src/screens/settings/display_settings_page.dart new
+80
@@ -0,0 +1,80 @@
1 +import 'package:cake_wallet/entities/fiat_currency.dart';
2 +import 'package:cake_wallet/entities/language_service.dart';
3 +import 'package:cake_wallet/generated/i18n.dart';
4 +import 'package:cake_wallet/src/screens/base_page.dart';
5 +import 'package:cake_wallet/src/screens/settings/widgets/settings_choices_cell.dart';
6 +import 'package:cake_wallet/src/screens/settings/widgets/settings_picker_cell.dart';
7 +import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart';
8 +import 'package:cake_wallet/themes/theme_base.dart';
9 +import 'package:cake_wallet/themes/theme_list.dart';
10 +import 'package:cake_wallet/view_model/settings/choices_list_item.dart';
11 +import 'package:cake_wallet/view_model/settings/settings_view_model.dart';
12 +import 'package:cake_wallet/wallet_type_utils.dart';
13 +import 'package:flutter/material.dart';
14 +import 'package:flutter_mobx/flutter_mobx.dart';
15 +
16 +class DisplaySettingsPage extends BasePage {
17 + DisplaySettingsPage(this.settingsViewModel);
18 +
19 + @override
20 + String get title => S.current.display_settings;
21 +
22 + final SettingsViewModel settingsViewModel;
23 +
24 + @override
25 + Widget body(BuildContext context) {
26 + return Observer(builder: (_) {
27 + return Container(
28 + padding: EdgeInsets.only(top: 10),
29 + child: Column(
30 + children: [
31 + SettingsSwitcherCell(
32 + title: S.current.settings_save_recipient_address,
33 + value: settingsViewModel.shouldSaveRecipientAddress,
34 + onValueChange: (BuildContext _, bool value) {
35 + settingsViewModel.setShouldSaveRecipientAddress(value);
36 + }),
37 + if (!isHaven)
38 + SettingsPickerCell<FiatCurrency>(
39 + title: S.current.settings_currency,
40 + searchHintText: S.current.search_currency,
41 + items: FiatCurrency.all,
42 + selectedItem: settingsViewModel.fiatCurrency,
43 + onItemSelected: (FiatCurrency currency) => settingsViewModel.setFiatCurrency(currency),
44 + images: FiatCurrency.all.map((e) => Image.asset("assets/images/flags/${e.countryCode}.png")).toList(),
45 + isGridView: true,
46 + matchingCriteria: (FiatCurrency currency, String searchText) {
47 + return currency.title.toLowerCase().contains(searchText) ||
48 + currency.fullName.toLowerCase().contains(searchText);
49 + },
50 + ),
51 + SettingsPickerCell<String>(
52 + title: S.current.settings_change_language,
53 + searchHintText: S.current.search_language,
54 + items: LanguageService.list.keys.toList(),
55 + displayItem: (dynamic code) {
56 + return LanguageService.list[code] ?? '';
57 + },
58 + selectedItem: settingsViewModel.languageCode,
59 + onItemSelected: settingsViewModel.onLanguageSelected,
60 + images: LanguageService.list.keys
61 + .map((e) => Image.asset("assets/images/flags/${LanguageService.localeCountryCode[e]}.png"))
62 + .toList(),
63 + matchingCriteria: (String code, String searchText) {
64 + return LanguageService.list[code]?.toLowerCase().contains(searchText) ?? false;
65 + },
66 + ),
67 + SettingsChoicesCell(
68 + ChoicesListItem<ThemeBase>(
69 + title: S.current.color_theme,
70 + items: ThemeList.all,
71 + selectedItem: settingsViewModel.theme,
72 + onItemSelected: (ThemeBase theme) => settingsViewModel.setTheme(theme),
73 + ),
74 + ),
75 + ],
76 + ),
77 + );
78 + });
79 + }
80 +}
lib/src/screens/settings/other_settings_page.dart new
+45
@@ -0,0 +1,45 @@
1 +import 'package:cake_wallet/generated/i18n.dart';
2 +import 'package:cake_wallet/routes.dart';
3 +import 'package:cake_wallet/src/screens/base_page.dart';
4 +import 'package:cake_wallet/src/screens/settings/widgets/settings_cell_with_arrow.dart';
5 +import 'package:cake_wallet/src/screens/settings/widgets/settings_picker_cell.dart';
6 +import 'package:cake_wallet/src/screens/settings/widgets/settings_version_cell.dart';
7 +import 'package:cake_wallet/src/widgets/standard_list.dart';
8 +import 'package:cake_wallet/view_model/settings/settings_view_model.dart';
9 +import 'package:cw_core/transaction_priority.dart';
10 +import 'package:flutter/material.dart';
11 +import 'package:flutter_mobx/flutter_mobx.dart';
12 +
13 +class OtherSettingsPage extends BasePage {
14 + OtherSettingsPage(this._settingsViewModel);
15 +
16 + @override
17 + String get title => S.current.other_settings;
18 +
19 + final SettingsViewModel _settingsViewModel;
20 +
21 + @override
22 + Widget body(BuildContext context) {
23 + return Observer(builder: (_) {
24 + return Container(
25 + padding: EdgeInsets.only(top: 10),
26 + child: Column(children: [
27 + SettingsPickerCell<TransactionPriority>(
28 + title: S.current.settings_fee_priority,
29 + items: priorityForWalletType(_settingsViewModel.walletType),
30 + displayItem: _settingsViewModel.getDisplayPriority,
31 + selectedItem: _settingsViewModel.transactionPriority,
32 + onItemSelected: _settingsViewModel.onDisplayPrioritySelected,
33 + ),
34 + SettingsCellWithArrow(
35 + title: S.current.settings_terms_and_conditions,
36 + handler: (BuildContext context) => Navigator.of(context).pushNamed(Routes.readDisclaimer),
37 + ),
38 + StandardListSeparator(padding: EdgeInsets.symmetric(horizontal: 24)),
39 + Spacer(),
40 + SettingsVersionCell(title: S.of(context).version(_settingsViewModel.currentVersion))
41 + ]),
42 + );
43 + });
44 + }
45 +}
lib/src/screens/settings/privacy_page.dart new
+30
@@ -0,0 +1,30 @@
1 +import 'package:cake_wallet/generated/i18n.dart';
2 +import 'package:cake_wallet/src/screens/base_page.dart';
3 +import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart';
4 +import 'package:cake_wallet/view_model/settings/settings_view_model.dart';
5 +import 'package:flutter/material.dart';
6 +import 'package:flutter_mobx/flutter_mobx.dart';
7 +
8 +class PrivacyPage extends BasePage {
9 + PrivacyPage(this.settingsViewModel);
10 +
11 + @override
12 + String get title => S.current.privacy_settings;
13 +
14 + final SettingsViewModel settingsViewModel;
15 +
16 + @override
17 + Widget body(BuildContext context) {
18 + return Container(
19 + padding: EdgeInsets.only(top: 10),
20 + child: Observer(builder: (_) {
21 + return SettingsSwitcherCell(
22 + title: S.current.settings_save_recipient_address,
23 + value: settingsViewModel.shouldSaveRecipientAddress,
24 + onValueChange: (BuildContext _, bool value) {
25 + settingsViewModel.setShouldSaveRecipientAddress(value);
26 + });
27 + }),
28 + );
29 + }
30 +}
lib/src/screens/settings/security_backup_page.dart new
+84
@@ -0,0 +1,84 @@
1 +import 'package:cake_wallet/routes.dart';
2 +import 'package:cake_wallet/src/screens/auth/auth_page.dart';
3 +import 'package:cake_wallet/src/screens/base_page.dart';
4 +import 'package:cake_wallet/generated/i18n.dart';
5 +import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
6 +import 'package:cake_wallet/src/screens/settings/widgets/settings_cell_with_arrow.dart';
7 +import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart';
8 +import 'package:cake_wallet/src/widgets/standard_list.dart';
9 +import 'package:cake_wallet/view_model/settings/settings_view_model.dart';
10 +import 'package:flutter/material.dart';
11 +import 'package:flutter_mobx/flutter_mobx.dart';
12 +
13 +class SecurityBackupPage extends BasePage {
14 + SecurityBackupPage(this.settingsViewModel);
15 +
16 + @override
17 + String get title => S.current.security_and_backup;
18 +
19 + final SettingsViewModel settingsViewModel;
20 +
21 + @override
22 + Widget body(BuildContext context) {
23 + return Container(
24 + padding: EdgeInsets.only(top: 10),
25 + child: Column(mainAxisSize: MainAxisSize.min, children: [
26 + SettingsCellWithArrow(
27 + title: S.current.show_keys,
28 + handler: (_) => Navigator.of(context).pushNamed(Routes.auth,
29 + arguments: (bool isAuthenticatedSuccessfully, AuthPageState auth) {
30 + if (isAuthenticatedSuccessfully) {
31 + auth.close(route: Routes.showKeys);
32 + }
33 + }),
34 + ),
35 + StandardListSeparator(padding: EdgeInsets.symmetric(horizontal: 24)),
36 + SettingsCellWithArrow(
37 + title: S.current.create_backup,
38 + handler: (_) => Navigator.of(context).pushNamed(Routes.auth,
39 + arguments: (bool isAuthenticatedSuccessfully, AuthPageState auth) {
40 + if (isAuthenticatedSuccessfully) {
41 + auth.close(route: Routes.backup);
42 + }
43 + }),
44 + ),
45 + StandardListSeparator(padding: EdgeInsets.symmetric(horizontal: 24)),
46 + SettingsCellWithArrow(
47 + title: S.current.settings_change_pin,
48 + handler: (_) => Navigator.of(context).pushNamed(Routes.auth,
49 + arguments: (bool isAuthenticatedSuccessfully, AuthPageState auth) {
50 + auth.close(
51 + route: isAuthenticatedSuccessfully ? Routes.setupPin : null,
52 + arguments: (PinCodeState<PinCodeWidget> setupPinContext, String _) {
53 + setupPinContext.close();
54 + },
55 + );
56 + })),
57 + StandardListSeparator(padding: EdgeInsets.symmetric(horizontal: 24)),
58 + Observer(builder: (_) {
59 + return SettingsSwitcherCell(
60 + title: S.current.settings_allow_biometrical_authentication,
61 + value: settingsViewModel.allowBiometricalAuthentication,
62 + onValueChange: (BuildContext context, bool value) {
63 + if (value) {
64 + Navigator.of(context).pushNamed(Routes.auth,
65 + arguments: (bool isAuthenticatedSuccessfully, AuthPageState auth) async {
66 + if (isAuthenticatedSuccessfully) {
67 + if (await settingsViewModel.biometricAuthenticated()) {
68 + settingsViewModel.setAllowBiometricalAuthentication(isAuthenticatedSuccessfully);
69 + }
70 + } else {
71 + settingsViewModel.setAllowBiometricalAuthentication(isAuthenticatedSuccessfully);
72 + }
73 +
74 + auth.close();
75 + });
76 + } else {
77 + settingsViewModel.setAllowBiometricalAuthentication(value);
78 + }
79 + });
80 + }),
81 + ]),
82 + );
83 + }
84 +}
lib/src/screens/settings/settings.dart deleted
-98
@@ -1,98 +0,0 @@
1 -import 'package:cake_wallet/src/screens/settings/widgets/settings_choices_cell.dart';
2 -import 'package:cake_wallet/src/screens/settings/widgets/settings_version_cell.dart';
3 -import 'package:cake_wallet/view_model/settings/choices_list_item.dart';
4 -import 'package:cake_wallet/view_model/settings/version_list_item.dart';
5 -import 'package:flutter/material.dart';
6 -import 'package:flutter/cupertino.dart';
7 -import 'package:flutter_mobx/flutter_mobx.dart';
8 -import 'package:cake_wallet/generated/i18n.dart';
9 -import 'package:cake_wallet/view_model/settings/settings_view_model.dart';
10 -import 'package:cake_wallet/view_model/settings/link_list_item.dart';
11 -import 'package:cake_wallet/view_model/settings/picker_list_item.dart';
12 -import 'package:cake_wallet/view_model/settings/regular_list_item.dart';
13 -import 'package:cake_wallet/view_model/settings/switcher_list_item.dart';
14 -import 'package:cake_wallet/src/screens/settings/widgets/settings_link_provider_cell.dart';
15 -import 'package:cake_wallet/src/screens/settings/widgets/settings_cell_with_arrow.dart';
16 -import 'package:cake_wallet/src/screens/settings/widgets/settings_picker_cell.dart';
17 -import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart';
18 -import 'package:cake_wallet/src/widgets/standard_list.dart';
19 -import 'package:cake_wallet/src/screens/base_page.dart';
20 -
21 -class SettingsPage extends BasePage {
22 - SettingsPage(this.settingsViewModel);
23 -
24 - final SettingsViewModel settingsViewModel;
25 -
26 - @override
27 - String get title => S.current.settings_title;
28 -
29 - @override
30 - Widget body(BuildContext context) {
31 - // FIX-ME: Added `context` it was not used here before, maby bug ?
32 - return SectionStandardList(
33 - context: context,
34 - sectionCount: settingsViewModel.sections.length,
35 - itemCounter: (int sectionIndex) {
36 - if (sectionIndex < settingsViewModel.sections.length) {
37 - return settingsViewModel.sections[sectionIndex].length;
38 - }
39 -
40 - return 0;
41 - },
42 - itemBuilder: (_, sectionIndex, itemIndex) {
43 - final item = settingsViewModel.sections[sectionIndex][itemIndex];
44 -
45 - if (item is PickerListItem) {
46 - return Observer(builder: (_) {
47 - return SettingsPickerCell<Object>(
48 - displayItem: item.displayItem,
49 - title: item.title,
50 - selectedItem: item.selectedItem(),
51 - items: item.items,
52 - onItemSelected: (dynamic value) => item.onItemSelected(value),
53 - images: item.images,
54 - searchHintText: item.searchHintText,
55 - isGridView: item.isGridView,
56 - matchingCriteria: (dynamic value, String searchText) => item.matchingCriteria(value, searchText),
57 - );
58 - });
59 - }
60 -
61 - if (item is SwitcherListItem) {
62 - return Observer(builder: (_) {
63 - return SettingsSwitcherCell(
64 - title: item.title,
65 - value: item.value(),
66 - onValueChange: item.onValueChange);
67 - });
68 - }
69 -
70 - if (item is RegularListItem) {
71 - return SettingsCellWithArrow(
72 - title: item.title, handler: item.handler);
73 - }
74 -
75 - if (item is LinkListItem) {
76 - return SettingsLinkProviderCell(
77 - title: item.title,
78 - icon: item.icon,
79 - link: item.link,
80 - linkTitle: item.linkTitle);
81 - }
82 -
83 - if (item is VersionListItem) {
84 - return Observer(builder: (_) {
85 - return SettingsVersionCell(
86 - title:
87 - S.of(context).version(settingsViewModel.currentVersion));
88 - });
89 - }
90 -
91 - if (item is ChoicesListItem) {
92 - return SettingsChoicesCell(item);
93 - }
94 -
95 - return Container();
96 - });
97 - }
98 -}
lib/src/widgets/standard_list.dart
+3 -1
@@ -123,6 +123,7 @@ class SectionStandardList extends StatelessWidget {
123 required this.itemBuilder,
124 required this.sectionCount,
125 required BuildContext context,
126 + this.dividerPadding = const EdgeInsets.only(left: 24),
127 this.themeColor,
128 this.dividerThemeColor,
129 this.sectionTitleBuilder,
@@ -149,6 +150,7 @@ class SectionStandardList extends StatelessWidget {
150 final List<Widget> totalRows;
151 final Color? themeColor;
152 final Color? dividerThemeColor;
153 + final EdgeInsets dividerPadding;
154
155 List<Widget> transform(
156 bool hasTopSeparator,
@@ -178,7 +180,7 @@ class SectionStandardList extends StatelessWidget {
180
181 items.add(sectionIndex + 1 != sectionCount
182 ? SectionHeaderListRow()
181 - : StandardListSeparator(padding: EdgeInsets.only(left: 24)));
183 + : StandardListSeparator(padding: dividerPadding));
184 }
185
186 return items;
lib/view_model/settings/settings_view_model.dart
+42 -165
@@ -1,11 +1,6 @@
1 -import 'package:cake_wallet/entities/language_service.dart';
1 import 'package:cake_wallet/store/yat/yat_store.dart';
3 -import 'package:cake_wallet/view_model/settings/choices_list_item.dart';
4 -import 'package:flutter/cupertino.dart';
2 import 'package:mobx/mobx.dart';
3 import 'package:package_info/package_info.dart';
7 -import 'package:cake_wallet/routes.dart';
8 -import 'package:cake_wallet/generated/i18n.dart';
4 import 'package:cw_core/wallet_base.dart';
5 import 'package:cake_wallet/store/settings_store.dart';
6 import 'package:cake_wallet/entities/biometric_auth.dart';
@@ -16,21 +11,12 @@ import 'package:cw_core/node.dart';
11 import 'package:cake_wallet/monero/monero.dart';
12 import 'package:cake_wallet/haven/haven.dart';
13 import 'package:cake_wallet/entities/action_list_display_mode.dart';
19 -import 'package:cake_wallet/view_model/settings/version_list_item.dart';
20 -import 'package:cake_wallet/view_model/settings/picker_list_item.dart';
21 -import 'package:cake_wallet/view_model/settings/regular_list_item.dart';
22 -import 'package:cake_wallet/view_model/settings/settings_list_item.dart';
23 -import 'package:cake_wallet/view_model/settings/switcher_list_item.dart';
24 -import 'package:cake_wallet/src/screens/auth/auth_page.dart';
14 import 'package:cake_wallet/bitcoin/bitcoin.dart';
15 import 'package:cw_core/transaction_history.dart';
16 import 'package:cw_core/balance.dart';
17 import 'package:cw_core/transaction_info.dart';
18 import 'package:cw_core/transaction_priority.dart';
19 import 'package:cake_wallet/themes/theme_base.dart';
31 -import 'package:cake_wallet/themes/theme_list.dart';
32 -import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
33 -import 'package:cake_wallet/wallet_type_utils.dart';
20
21 part 'settings_view_model.g.dart';
22
@@ -59,9 +45,9 @@ abstract class SettingsViewModelBase with Store {
45 TransactionInfo>
46 wallet)
47 : itemHeaders = {},
62 - _walletType = wallet.type,
48 + walletType = wallet.type,
49 + _wallet = wallet,
50 _biometricAuth = BiometricAuth(),
64 - sections = <List<SettingsListItem>>[],
51 currentVersion = '' {
52 PackageInfo.fromPlatform().then(
53 (PackageInfo packageInfo) => currentVersion = packageInfo.version);
@@ -97,171 +83,30 @@ abstract class SettingsViewModelBase with Store {
83 // createNewYatUrl += '?sub1=' + createNewYatUrlParameters;
84 //}
85
100 -
101 - sections = [
102 - [
103 - SwitcherListItem(
104 - title: S.current.settings_display_balance,
105 - value: () => balanceDisplayMode == BalanceDisplayMode.displayableBalance,
106 - onValueChange: (_, bool value) {
107 - if (value) {
108 - _settingsStore.balanceDisplayMode = BalanceDisplayMode.displayableBalance;
109 - } else {
110 - _settingsStore.balanceDisplayMode = BalanceDisplayMode.hiddenBalance;
111 - }
112 - },
113 - ),
114 - if (!isHaven)
115 - PickerListItem(
116 - title: S.current.settings_currency,
117 - searchHintText: S.current.search_currency,
118 - items: FiatCurrency.all,
119 - selectedItem: () => fiatCurrency,
120 - onItemSelected: (FiatCurrency currency) =>
121 - setFiatCurrency(currency),
122 - images: FiatCurrency.all.map(
123 - (e) => Image.asset("assets/images/flags/${e.countryCode}.png"))
124 - .toList(),
125 - isGridView: true,
126 - matchingCriteria: (FiatCurrency currency, String searchText) {
127 - return currency.title.toLowerCase().contains(searchText) || currency.fullName.toLowerCase().contains(searchText);
128 - },
129 - ),
130 - PickerListItem(
131 - title: S.current.settings_fee_priority,
132 - items: priorityForWalletType(wallet.type),
133 - displayItem: (dynamic priority) {
134 - final _priority = priority as TransactionPriority;
135 -
136 - if (wallet.type == WalletType.bitcoin
137 - || wallet.type == WalletType.litecoin) {
138 - final rate = bitcoin!.getFeeRate(wallet, _priority);
139 - return bitcoin!.bitcoinTransactionPriorityWithLabel(_priority, rate);
140 - }
141 -
142 - return priority.toString();
143 - },
144 - selectedItem: () => transactionPriority,
145 - onItemSelected: (TransactionPriority priority) =>
146 - _settingsStore.priority[wallet.type] = priority),
147 - SwitcherListItem(
148 - title: S.current.settings_save_recipient_address,
149 - value: () => shouldSaveRecipientAddress,
150 - onValueChange: (_, bool value) =>
151 - setShouldSaveRecipientAddress(value))
152 - ],
153 - [
154 - RegularListItem(
155 - title: S.current.settings_change_pin,
156 - handler: (BuildContext context) {
157 - Navigator.of(context).pushNamed(Routes.auth, arguments:
158 - (bool isAuthenticatedSuccessfully, AuthPageState auth) {
159 - auth.close(
160 - route: isAuthenticatedSuccessfully ? Routes.setupPin : null,
161 - arguments: (PinCodeState<PinCodeWidget> setupPinContext,
162 - String _) {
163 - setupPinContext.close();
164 - },
165 - );
166 - });
167 - }),
168 - PickerListItem(
169 - title: S.current.settings_change_language,
170 - searchHintText: S.current.search_language,
171 - items: LanguageService.list.keys.toList(),
172 - displayItem: (dynamic code) {
173 - return LanguageService.list[code] ?? '';
174 - },
175 - selectedItem: () => _settingsStore.languageCode,
176 - onItemSelected: (String code) {
177 - _settingsStore.languageCode = code;
178 - },
179 - images: LanguageService.list.keys.map(
180 - (e) => Image.asset("assets/images/flags/${LanguageService.localeCountryCode[e]}.png"))
181 - .toList(),
182 - matchingCriteria: (String code, String searchText) {
183 - return LanguageService.list[code]?.toLowerCase().contains(searchText) ?? false;
184 - },
185 - ),
186 - SwitcherListItem(
187 - title: S.current.settings_allow_biometrical_authentication,
188 - value: () => allowBiometricalAuthentication,
189 - onValueChange: (BuildContext context, bool value) {
190 - if (value) {
191 - Navigator.of(context).pushNamed(Routes.auth, arguments:
192 - (bool isAuthenticatedSuccessfully,
193 - AuthPageState auth) async {
194 - if (isAuthenticatedSuccessfully) {
195 - if (await _biometricAuth.canCheckBiometrics() &&
196 - await _biometricAuth.isAuthenticated()) {
197 - setAllowBiometricalAuthentication(
198 - isAuthenticatedSuccessfully);
199 - }
200 - } else {
201 - setAllowBiometricalAuthentication(
202 - isAuthenticatedSuccessfully);
203 - }
204 -
205 - auth.close();
206 - });
207 - } else {
208 - setAllowBiometricalAuthentication(value);
209 - }
210 - }),
211 - ChoicesListItem(
212 - title: S.current.color_theme,
213 - items: ThemeList.all,
214 - selectedItem: theme,
215 - onItemSelected: (ThemeBase theme) => _settingsStore.currentTheme = theme,
216 - ),
217 - ],
218 - //[
219 - //if (_yatStore.emoji.isNotEmpty) ...[
220 - // LinkListItem(
221 - // title: S.current.manage_yats,
222 - // link: manageYatUrl,
223 - // linkTitle: ''),
224 - //] else ...[
225 - //LinkListItem(
226 - // title: S.current.connect_yats,
227 - // link: connectYatUrl,
228 - // linkTitle: ''),
229 - //LinkListItem(
230 - // title: 'Create new Yats',
231 - // link: createNewYatUrl,
232 - // linkTitle: '')
233 - //]
234 - //],
235 - [
236 - RegularListItem(
237 - title: S.current.settings_terms_and_conditions,
238 - handler: (BuildContext context) =>
239 - Navigator.of(context).pushNamed(Routes.readDisclaimer),
240 - )
241 - ],
242 - [VersionListItem(title: currentVersion)]
243 - ];
86 }
87
88 @observable
89 String currentVersion;
90
91 @computed
250 - Node get node => _settingsStore.getCurrentNode(_walletType);
92 + Node get node => _settingsStore.getCurrentNode(walletType);
93
94 @computed
95 FiatCurrency get fiatCurrency => _settingsStore.fiatCurrency;
96
97 + @computed
98 + String get languageCode => _settingsStore.languageCode;
99 +
100 @computed
101 ObservableList<ActionListDisplayMode> get actionlistDisplayMode =>
102 _settingsStore.actionlistDisplayMode;
103
104 @computed
105 TransactionPriority get transactionPriority {
261 - final priority = _settingsStore.priority[_walletType];
106 + final priority = _settingsStore.priority[walletType];
107
108 if (priority == null) {
264 - throw Exception('Unexpected type ${_walletType.toString()}');
109 + throw Exception('Unexpected type ${walletType.toString()}');
110 }
111
112 return priority;
@@ -285,11 +130,12 @@ abstract class SettingsViewModelBase with Store {
130 bool get isBitcoinBuyEnabled => _settingsStore.isBitcoinBuyEnabled;
131
132 final Map<String, String> itemHeaders;
288 - List<List<SettingsListItem>> sections;
133 final SettingsStore _settingsStore;
134 final YatStore _yatStore;
291 - final WalletType _walletType;
135 + final WalletType walletType;
136 final BiometricAuth _biometricAuth;
137 + final WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
138 + TransactionInfo> _wallet;
139
140 @action
141 void setBalanceDisplayMode(BalanceDisplayMode value) =>
@@ -333,4 +179,35 @@ abstract class SettingsViewModelBase with Store {
179
180 @action
181 void _showTrades() => actionlistDisplayMode.add(ActionListDisplayMode.trades);
182 +
183 + @action
184 + Future<bool> biometricAuthenticated()async{
185 + return await _biometricAuth.canCheckBiometrics() && await _biometricAuth.isAuthenticated();
186 + }
187 +
188 + @action
189 + void onLanguageSelected (String code) {
190 + _settingsStore.languageCode = code;
191 + }
192 +
193 + @action
194 + void setTheme(ThemeBase newTheme){
195 + _settingsStore.currentTheme = newTheme;
196 + }
197 +
198 + String getDisplayPriority(TransactionPriority priority) {
199 + final _priority = priority;
200 +
201 + if (_wallet.type == WalletType.bitcoin
202 + || _wallet.type == WalletType.litecoin) {
203 + final rate = bitcoin!.getFeeRate(_wallet, _priority);
204 + return bitcoin!.bitcoinTransactionPriorityWithLabel(_priority, rate);
205 + }
206 +
207 + return priority.toString();
208 + }
209 +
210 + void onDisplayPrioritySelected(TransactionPriority priority) =>
211 + _settingsStore.priority[_wallet.type] = priority;
212 +
213 }
res/values/strings_de.arb
+5 -1
@@ -651,5 +651,9 @@
651 "ignor": "Ignorieren",
652 "use_suggested": "Vorgeschlagen verwenden",
653 "do_not_share_warning_text" : "Teilen Sie diese nicht mit anderen, einschließlich des Supports.\n\nSie werden Ihr Geld stehlen!",
654 - "help": "hilfe"
654 + "help": "hilfe",
655 + "privacy_settings": "Datenschutzeinstellungen",
656 + "privacy": "Datenschutz",
657 + "display_settings": "Anzeigeeinstellungen",
658 + "other_settings": "Andere Einstellungen"
659 }
res/values/strings_en.arb
+8 -1
@@ -651,5 +651,12 @@
651 "ignor": "Ignore",
652 "use_suggested": "Use Suggested",
653 "do_not_share_warning_text" : "Do not share these with anyone else, including support.\n\nThey will steal your money!",
654 - "help": "help"
654 + "help": "help",
655 + "connection_sync": "Connection and sync",
656 + "security_and_backup": "Security and backup",
657 + "create_backup": "Create backup",
658 + "privacy_settings": "Privacy settings",
659 + "privacy": "Privacy",
660 + "display_settings": "Display settings",
661 + "other_settings": "Other settings"
662 }
res/values/strings_es.arb
+5 -1
@@ -651,5 +651,9 @@
651 "ignor": "Pasar por alto",
652 "use_suggested": "Usar sugerido",
653 "do_not_share_warning_text" : "No comparta estos con nadie más, incluido el soporte.\n\n¡Te robarán tu dinero!",
654 - "help": "ayuda"
654 + "help": "ayuda",
655 + "privacy_settings": "Configuración de privacidad",
656 + "privacy": "Privacidad",
657 + "display_settings": "Configuración de pantalla",
658 + "other_settings": "Otras configuraciones"
659 }
res/values/strings_fr.arb
+5 -1
@@ -649,5 +649,9 @@
649 "ignor": "Ignorer",
650 "use_suggested": "Utilisation suggérée",
651 "do_not_share_warning_text" : "Ne les partagez avec personne d'autre, y compris avec l'assistance.\n\nIls vont voler votre argent!",
652 - "help": "aider"
652 + "help": "aider",
653 + "privacy_settings": "Paramètres de confidentialité",
654 + "privacy": "Confidentialité",
655 + "display_settings": "Paramètres d'affichage",
656 + "other_settings": "Autres paramètres"
657 }
res/values/strings_hi.arb
+5 -1
@@ -651,5 +651,9 @@
651 "ignor": "नज़रअंदाज़ करना",
652 "use_suggested": "सुझाए गए का प्रयोग करें",
653 "do_not_share_warning_text" : "इन्हें समर्थन सहित किसी और के साथ साझा न करें।\n\nवे आपका पैसा चुरा लेंगे!",
654 - "help": "मदद करना"
654 + "help": "मदद करना",
655 + "privacy_settings": "गोपनीयता सेटिंग्स",
656 + "privacy": "गोपनीयता",
657 + "display_settings": "प्रदर्शन सेटिंग्स",
658 + "other_settings": "अन्य सेटिंग्स"
659 }
res/values/strings_hr.arb
+5 -1
@@ -651,5 +651,9 @@
651 "ignor": "Zanemariti",
652 "use_suggested": "Koristite predloženo",
653 "do_not_share_warning_text" : "Nemojte ih dijeliti ni s kim, uključujući podršku.\n\nUkrast će vam novac!",
654 - "help": "pomozite"
654 + "help": "pomozite",
655 + "privacy_settings": "Postavke privatnosti",
656 + "privacy": "Privatnost",
657 + "display_settings": "Postavke zaslona",
658 + "other_settings": "Ostale postavke"
659 }
res/values/strings_it.arb
+5 -1
@@ -651,5 +651,9 @@
651 "ignor": "Ignorare",
652 "use_suggested": "Usa suggerito",
653 "do_not_share_warning_text" : "Non condividerli con nessun altro, incluso il supporto.\n\nTi ruberanno i soldi!",
654 - "help": "aiuto"
654 + "help": "aiuto",
655 + "privacy_settings": "Impostazioni privacy",
656 + "privacy": "Privacy",
657 + "display_settings": "Impostazioni di visualizzazione",
658 + "other_settings": "Altre impostazioni"
659 }
res/values/strings_ja.arb
+5 -1
@@ -651,5 +651,9 @@
651 "ignor": "無視",
652 "use_suggested": "推奨を使用",
653 "do_not_share_warning_text" : "サポートを含め、これらを他の誰とも共有しないでください。\n\n彼らはあなたのお金を盗みます!",
654 - "help": "ヘルプ"
654 + "help": "ヘルプ",
655 + "privacy_settings": "プライバシー設定",
656 + "privacy": "プライバシー",
657 + "display_settings": "表示設定",
658 + "other_settings": "その他の設定"
659 }
res/values/strings_ko.arb
+5 -1
@@ -651,5 +651,9 @@
651 "ignor": "무시하다",
652 "use_suggested": "추천 사용",
653 "do_not_share_warning_text" : "지원을 포함하여 다른 사람과 이러한 정보를 공유하지 마십시오.\n\n그들은 당신의 돈을 훔칠 것입니다!",
654 - "help": "돕다"
654 + "help": "돕다",
655 + "privacy_settings": "개인정보 설정",
656 + "privacy": "프라이버시",
657 + "display_settings": "디스플레이 설정",
658 + "other_settings": "기타 설정"
659 }
res/values/strings_nl.arb
+5 -1
@@ -651,5 +651,9 @@
651 "ignor": "Negeren",
652 "use_suggested": "Gebruik aanbevolen",
653 "do_not_share_warning_text" : "Deel deze met niemand anders, ook niet met support.\n\nZe zullen je geld stelen!",
654 - "help": "helpen"
654 + "help": "helpen",
655 + "privacy_settings": "Privacy-instellingen",
656 + "privacy": "Privacy",
657 + "display_settings": "Weergave-instellingen",
658 + "other_settings": "Andere instellingen"
659 }
res/values/strings_pl.arb
+5 -1
@@ -651,5 +651,9 @@
651 "ignor": "Ignorować",
652 "use_suggested": "Użyj sugerowane",
653 "do_not_share_warning_text" : "Nie udostępniaj ich nikomu innemu, w tym wsparcia.\n\nUkradną twoje pieniądze!",
654 - "help": "pomoc"
654 + "help": "pomoc",
655 + "privacy_settings": "Ustawienia prywatności",
656 + "privacy": "Prywatność",
657 + "display_settings": "Ustawienia wyświetlania",
658 + "other_settings": "Inne ustawienia"
659 }
res/values/strings_pt.arb
+5 -1
@@ -651,5 +651,9 @@
651 "ignor": "Ignorar",
652 "use_suggested": "Uso sugerido",
653 "do_not_share_warning_text" : "Não os compartilhe com mais ninguém, incluindo suporte.\n\nEles vão roubar seu dinheiro!",
654 - "help": "ajuda"
654 + "help": "ajuda",
655 + "privacy_settings": "Configurações de privacidade",
656 + "privacy": "Privacidade",
657 + "display_settings": "Configurações de exibição",
658 + "other_settings": "Outras configurações"
659 }
res/values/strings_ru.arb
+5 -1
@@ -651,5 +651,9 @@
651 "ignor": "Игнорировать",
652 "use_suggested": "Использовать предложенный",
653 "do_not_share_warning_text" : "Не делитесь ими с кем-либо еще, в том числе со службой поддержки.\n\nОни украдут ваши деньги!",
654 - "help": "помощь"
654 + "help": "помощь",
655 + "privacy_settings": "Настройки конфиденциальности",
656 + "privacy": "Конфиденциальность",
657 + "display_settings": "Настройки отображения",
658 + "other_settings": "Другие настройки"
659 }
res/values/strings_uk.arb
+6 -1
@@ -650,5 +650,10 @@
650 "ignor": "Ігнорувати",
651 "use_suggested": "Використати запропоноване",
652 "do_not_share_warning_text" : "Не повідомляйте їх нікому, включно зі службою підтримки.\n\nВони вкрадуть ваші гроші!",
653 - "help": "допомога"
653 + "help": "допомога",
654 + "privacy_settings": "Налаштування конфіденційності",
655 + "privacy": "Конфіденційність",
656 + "display_settings": "Налаштування дисплея",
657 + "other_settings": "Інші налаштування"
658 +
659 }
res/values/strings_zh.arb
+5 -1
@@ -649,5 +649,9 @@
649 "ignor": "忽视",
650 "use_suggested": "使用建议",
651 "do_not_share_warning_text" : "不要與其他任何人分享這些內容,包括支持。\n\n他們會偷你的錢!",
652 - "help": "帮助"
652 + "help": "帮助",
653 + "privacy_settings": "隐私设置",
654 + "privacy":"隐私",
655 + "display_settings": "显示设置",
656 + "other_settings": "其他设置"
657 }