What changed, and why it matters
This commit is a large user-interface redesign of the settings screens in the Cake Wallet mobile app. It replaces old settings widgets with newer components, reorganizes settings into new categories, adds new view models, and updates icons and navigation. There is no clear security vulnerability in the diff itself; it is primarily a cosmetic and structural refactor.
No immediate security action required. Treat as a normal UI refactor. If reviewing for release, verify that the reorganized settings pages still correctly enforce authentication gating (e.g., seed/keys route) and that feature-flagged options behave as expected.
Security signals we found
Large UI refactor with no obvious security-sensitive code changes
New view model added for connection/sync settings
Feature flag gating added for automatic node switching UI
Settings reorganized across pages; some routes and conditions changed
No changes to encryption, key handling, or network validation logic visible in diff
Evidence from the diff
The commit refactors multiple settings pages (display, connection/sync, privacy, nodes, other, MWEB, about) to use a new ModalPageWrapper, NewListSections, and updated list-item widgets. It introduces a ConnectionSyncViewModel and wires it through dependency injection, moves some settings between pages (e.g., WalletConnect to main settings, MWEB to privacy, domain lookups to connection/sync), and adds feature-flag gating for automatic node switching. The changes are mostly UI/UX and code organization; no cryptographic, authentication, or network-trust logic is altered in a way that introduces a vulnerability based on the supplied diff.
Changed components
lib/src/screens/settings/*lib/new-ui/pages/settings_page.dartlib/new-ui/widgets/modal_page_wrapper.dartlib/new-ui/widgets/receive_page/receive_top_bar.dartlib/src/screens/base_page.dartlib/di.dartlib/view_model/settings/connection_sync_view_model.dartInspect captured patch +1991 / −1373
diff --git a/assets/images/black_accent.svg b/assets/images/black_accent.svg
deleted file mode 100644
index 7e22d3b1..00000000
--- a/assets/images/black_accent.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-<svg width="92" height="173" viewBox="0 0 92 173" fill="none" xmlns="http://www.w3.org/2000/svg">
-<rect width="92" height="173" rx="10" fill="#131314"/>
-<rect x="16" y="8" width="59" height="9" rx="4.5" fill="#211F20"/>
-<rect x="8" y="152" width="75" height="14" rx="7" fill="#211F20"/>
-<rect x="8" y="37" width="75" height="30" rx="4" fill="#211F20"/>
-<rect x="10" y="31" width="16" height="3" fill="#B4B4B4"/>
-<rect x="12" y="41" width="34" height="3" fill="#B4B4B4"/>
-<rect x="12" y="46" width="34" height="3" fill="#B4B4B4"/>
-<rect x="12" y="51" width="26" height="3" fill="#B4B4B4"/>
-<rect x="12" y="56" width="26" height="3" fill="#B4B4B4"/>
-<rect x="71" y="54" width="8" height="3" fill="#B4B4B4"/>
-<rect x="71" y="44" width="8" height="8" rx="4" fill="#52B6F0"/>
-</svg>
diff --git a/assets/images/dark.svg b/assets/images/dark.svg
deleted file mode 100644
index 20baf68f..00000000
--- a/assets/images/dark.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-<svg width="92" height="173" viewBox="0 0 92 173" fill="none" xmlns="http://www.w3.org/2000/svg">
-<rect width="92" height="173" rx="10" fill="#1B284A"/>
-<rect x="16" y="8" width="59" height="9" rx="4.5" fill="#233461"/>
-<rect x="8" y="152" width="75" height="14" rx="7" fill="#233461"/>
-<rect x="8" y="37" width="75" height="30" rx="4" fill="#233461"/>
-<rect x="10" y="31" width="16" height="3" fill="#8C9FBB"/>
-<rect x="12" y="41" width="34" height="3" fill="#8C9FBB"/>
-<rect x="12" y="46" width="34" height="3" fill="#8C9FBB"/>
-<rect x="12" y="51" width="26" height="3" fill="#8C9FBB"/>
-<rect x="12" y="56" width="26" height="3" fill="#8C9FBB"/>
-<rect x="71" y="54" width="8" height="3" fill="#8C9FBB"/>
-<rect x="71" y="44" width="8" height="8" rx="4" fill="#91B0FF"/>
-</svg>
diff --git a/assets/images/light.svg b/assets/images/light.svg
deleted file mode 100644
index 183a13fd..00000000
--- a/assets/images/light.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-<svg width="92" height="173" viewBox="0 0 92 173" fill="none" xmlns="http://www.w3.org/2000/svg">
-<rect width="92" height="173" rx="10" fill="#EFEFF8"/>
-<rect x="16" y="8" width="59" height="9" rx="4.5" fill="#FBFBFD"/>
-<rect x="8" y="152" width="75" height="14" rx="7" fill="#FBFBFD"/>
-<rect x="8" y="37" width="75" height="30" rx="4" fill="#FBFBFD"/>
-<rect x="10" y="31" width="16" height="3" fill="#6C6772"/>
-<rect x="12" y="41" width="34" height="3" fill="#6C6772"/>
-<rect x="12" y="46" width="34" height="3" fill="#6C6772"/>
-<rect x="12" y="51" width="26" height="3" fill="#6C6772"/>
-<rect x="12" y="56" width="26" height="3" fill="#6C6772"/>
-<rect x="71" y="54" width="8" height="3" fill="#6C6772"/>
-<rect x="71" y="44" width="8" height="8" rx="4" fill="#4EBEFF"/>
-</svg>
diff --git a/assets/new-ui/black_accent.svg.vec b/assets/new-ui/black_accent.svg.vec
new file mode 100644
index 00000000..5d087f00
Binary files /dev/null and b/assets/new-ui/black_accent.svg.vec differ
diff --git a/assets/new-ui/cake-setting.svg.vec b/assets/new-ui/cake-setting.svg.vec
new file mode 100644
index 00000000..33efbf6b
Binary files /dev/null and b/assets/new-ui/cake-setting.svg.vec differ
diff --git a/assets/new-ui/chooser.svg.vec b/assets/new-ui/chooser.svg.vec
index 69befbc7..4f8ed136 100644
Binary files a/assets/new-ui/chooser.svg.vec and b/assets/new-ui/chooser.svg.vec differ
diff --git a/assets/new-ui/dark.svg.vec b/assets/new-ui/dark.svg.vec
new file mode 100644
index 00000000..d270f215
Binary files /dev/null and b/assets/new-ui/dark.svg.vec differ
diff --git a/assets/new-ui/light.svg.vec b/assets/new-ui/light.svg.vec
new file mode 100644
index 00000000..7971583f
Binary files /dev/null and b/assets/new-ui/light.svg.vec differ
diff --git a/assets/new-ui/privacy.svg.vec b/assets/new-ui/privacy.svg.vec
index f8d6e3e4..e50f9641 100644
Binary files a/assets/new-ui/privacy.svg.vec and b/assets/new-ui/privacy.svg.vec differ
diff --git a/assets/new-ui/security.svg.vec b/assets/new-ui/security.svg.vec
index 4ed940fc..97a589e9 100644
Binary files a/assets/new-ui/security.svg.vec and b/assets/new-ui/security.svg.vec differ
diff --git a/assets/new-ui/settings_row_icons/privacy.svg.vec b/assets/new-ui/settings_row_icons/privacy.svg.vec
index f8d6e3e4..e50f9641 100644
Binary files a/assets/new-ui/settings_row_icons/privacy.svg.vec and b/assets/new-ui/settings_row_icons/privacy.svg.vec differ
diff --git a/assets/new-ui/settings_row_icons/security.svg.vec b/assets/new-ui/settings_row_icons/security.svg.vec
index 4ed940fc..97a589e9 100644
Binary files a/assets/new-ui/settings_row_icons/security.svg.vec and b/assets/new-ui/settings_row_icons/security.svg.vec differ
diff --git a/assets/new-ui/settings_row_icons/wc.svg.vec b/assets/new-ui/settings_row_icons/wc.svg.vec
new file mode 100644
index 00000000..a071b14e
Binary files /dev/null and b/assets/new-ui/settings_row_icons/wc.svg.vec differ
diff --git a/assets/new-ui/wallet-setting.svg.vec b/assets/new-ui/wallet-setting.svg.vec
new file mode 100644
index 00000000..22d32c47
Binary files /dev/null and b/assets/new-ui/wallet-setting.svg.vec differ
diff --git a/assets/new-ui/wc.svg.vec b/assets/new-ui/wc.svg.vec
new file mode 100644
index 00000000..a071b14e
Binary files /dev/null and b/assets/new-ui/wc.svg.vec differ
diff --git a/lib/di.dart b/lib/di.dart
index a6b5c740..156a3624 100644
--- a/lib/di.dart
+++ b/lib/di.dart
@@ -252,6 +252,7 @@ import 'package:cake_wallet/view_model/send/fees_view_model.dart';
import 'package:cake_wallet/view_model/send/send_template_view_model.dart';
import 'package:cake_wallet/view_model/send/send_view_model.dart';
import 'package:cake_wallet/view_model/set_up_2fa_viewmodel.dart';
+import 'package:cake_wallet/view_model/settings/connection_sync_view_model.dart';
import 'package:cake_wallet/view_model/settings/display_settings_view_model.dart';
import 'package:cake_wallet/view_model/settings/mweb_settings_view_model.dart';
import 'package:cake_wallet/view_model/settings/other_settings_view_model.dart';
@@ -1131,7 +1132,9 @@ Future<void> setup({
return PowNodeListViewModel(_powNodeSource, appStore);
});
- getIt.registerFactory(() => ConnectionSyncPage(getIt.get<DashboardViewModel>()));
+ getIt.registerFactory(() => ConnectionSyncViewModel(getIt.get<SettingsStore>(), getIt.get<AppStore>().wallet!));
+
+ getIt.registerFactory(() => ConnectionSyncPage(getIt.get<ConnectionSyncViewModel>()));
getIt.registerFactory(() => SecurityBackupPage(getIt.get<SecuritySettingsViewModel>(),
getIt.get<AuthService>(), getIt.get<AppStore>().wallet!.isHardwareWallet));
@@ -1140,7 +1143,7 @@ Future<void> setup({
getIt.registerFactory(() => TrocadorProvidersPage(getIt.get<TrocadorProvidersViewModel>()));
- getIt.registerFactory(() => DomainLookupsPage(getIt.get<PrivacySettingsViewModel>()));
+ getIt.registerFactory(() => DomainLookupsPage(getIt.get<ConnectionSyncViewModel>()));
getIt.registerFactory(() => DisplaySettingsPage(getIt.get<DisplaySettingsViewModel>()));
@@ -1691,9 +1694,9 @@ Future<void> setup({
getIt.registerFactoryParam<ManageNodesPage, bool, void>((bool isPow, _) {
if (isPow) {
- return ManageNodesPage(isPow, powNodeListViewModel: getIt.get<PowNodeListViewModel>());
+ return ManageNodesPage(isPow, powNodeListViewModel: getIt.get<PowNodeListViewModel>(), dashboardViewModel: getIt.get<DashboardViewModel>());
}
- return ManageNodesPage(isPow, nodeListViewModel: getIt.get<NodeListViewModel>());
+ return ManageNodesPage(isPow, nodeListViewModel: getIt.get<NodeListViewModel>(), dashboardViewModel: getIt.get<DashboardViewModel>());
});
getIt.registerFactory(
diff --git a/lib/new-ui/pages/about_page.dart b/lib/new-ui/pages/about_page.dart
index 7a9a15ac..a869ba1a 100644
--- a/lib/new-ui/pages/about_page.dart
+++ b/lib/new-ui/pages/about_page.dart
@@ -2,11 +2,11 @@ import 'dart:math';
import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item_regular_row.dart';
import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/new-ui/widgets/modal_page_wrapper.dart';
import 'package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart';
import 'package:cake_wallet/src/widgets/cake_image_widget.dart';
import 'package:cake_wallet/src/widgets/new_list_row/new_list_section.dart';
import 'package:flutter/material.dart';
-import 'package:flutter_svg/svg.dart';
import 'package:url_launcher/url_launcher.dart';
// written by people who happened to read my slack message in 2025
@@ -52,61 +52,60 @@ class _AboutPageState extends State<AboutPage> {
@override
Widget build(BuildContext context) {
- return Container(
- color: Theme.of(context).colorScheme.surface,
- child: Column(children: [
- ModalTopBar(
- title: S.of(context).about,
- leadingIcon: Icon(Icons.arrow_back_ios_new),
- onLeadingPressed: Navigator.of(context).pop,
- ),
- Column(
- children: [
- Column(
- spacing: 16,
- children: [
- SizedBox(),
- GestureDetector(
- onTap: _easterEgg,
- child: CakeImageWidget(
- imageUrl: "assets/new-ui/cake_squircle_icon.svg",
- width: 128,
- height: 128,
- ),
- ),
- Row(
- mainAxisAlignment: MainAxisAlignment.center,
- spacing: 8,
- children: [
- Text(
- "Cake Wallet",
- style: TextStyle(fontSize: 32, fontWeight: FontWeight.w500),
+ return ModalPageWrapper(
+ topBar: ModalTopBar(
+ title: S.of(context).about,
+ leadingIcon: Icon(Icons.arrow_back_ios_new),
+ onLeadingPressed: Navigator.of(context).pop,
+ ),
+ content: Container(
+ color: Theme.of(context).colorScheme.surface,
+ child: Column(children: [
+ Column(
+ children: [
+ Column(
+ spacing: 16,
+ children: [
+ SizedBox(),
+ GestureDetector(
+ onTap: _easterEgg,
+ child: CakeImageWidget(
+ imageUrl: "assets/new-ui/cake_squircle_icon.svg",
+ width: 128,
+ height: 128,
),
- Text(widget.appVersion,
- style: TextStyle(
- fontSize: 32,
- fontWeight: FontWeight.w500,
- color: Theme.of(context).colorScheme.onSurfaceVariant))
- ],
- ),
- Padding(
- padding: const EdgeInsets.symmetric(horizontal: 12.0),
- child: Wrap(
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ spacing: 8,
children: [
Text(
- _bottomText,
- textAlign: TextAlign.center,
- style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant),
+ "Cake Wallet",
+ style: TextStyle(fontSize: 32, fontWeight: FontWeight.w500),
),
+ Text(widget.appVersion,
+ style: TextStyle(
+ fontSize: 32,
+ fontWeight: FontWeight.w500,
+ color: Theme.of(context).colorScheme.onSurfaceVariant))
],
),
- ),
- ],
- ),
- SizedBox(height: 32),
- Padding(
- padding: const EdgeInsets.symmetric(horizontal: 16.0),
- child: NewListSections(sections: {
+ Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 12.0),
+ child: Wrap(
+ children: [
+ Text(
+ _bottomText,
+ textAlign: TextAlign.center,
+ style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant),
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ SizedBox(height: 32),
+ NewListSections(sections: {
"": [
ListItemRegularRow(
keyValue: "official website",
@@ -146,10 +145,10 @@ class _AboutPageState extends State<AboutPage> {
foregroundColor: Theme.of(context).colorScheme.primary,
trailingIconSize: 10)
]
- }),
- )
- ],
- )
- ]));
+ })
+ ],
+ )
+ ])),
+ );
}
}
diff --git a/lib/new-ui/pages/settings_page.dart b/lib/new-ui/pages/settings_page.dart
index 470d745b..76446f0f 100644
--- a/lib/new-ui/pages/settings_page.dart
+++ b/lib/new-ui/pages/settings_page.dart
@@ -9,6 +9,7 @@ import 'package:cake_wallet/src/widgets/new_list_row/new_list_section.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:flutter/material.dart';
+import 'package:flutter_svg/svg.dart';
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
import "package:cw_core/wallet_type.dart";
@@ -18,8 +19,12 @@ bool _falseFunc(DashboardViewModel _) => false;
bool _isBtc(DashboardViewModel vm) => vm.wallet.type == WalletType.bitcoin;
+bool _hasLightning(DashboardViewModel vm) => vm.hasLightning;
+
bool _hasMweb(DashboardViewModel vm) => vm.hasMweb;
+bool _hasWalletConnect(DashboardViewModel vm) => vm.hasWalletConnect;
+
bool _isCupcake(DashboardViewModel vm) => vm.wallet.hardwareWalletType == HardwareWalletType.cupcake;
class SettingsListItem {
@@ -42,21 +47,21 @@ class SettingsSectionData {
const SettingsSectionData(this.title, this.titleIconPath, this.items);
static SettingsSectionData walletSettings =
- SettingsSectionData(S.current.wallet_settings, "assets/new-ui/wallet_settings.svg", [
+ SettingsSectionData(S.current.wallet_settings, "assets/new-ui/wallet-setting.svg", [
SettingsListItem("assets/new-ui/settings_row_icons/nodes.svg", S.current.nodes, Routes.manageNodes),
SettingsListItem("assets/new-ui/settings_row_icons/privacy.svg", S.current.privacy, Routes.privacyPage),
SettingsListItem("assets/new-ui/settings_row_icons/seed.svg", S.current.seed_and_keys, Routes.showKeys,
routeArgs: true, requireAuth: true, use2fa: (vm)=>vm.settingsStore.shouldRequireTOTP2FAForAllSecurityAndBackupSettings),
- SettingsListItem("assets/new-ui/settings_row_icons/lightning_username.svg",
- "Lightning ${S.current.username}", Routes.lightningUsernamePage, condition: _isBtc),
- SettingsListItem("assets/new-ui/settings_row_icons/silent-payments.svg", S.current.silent_payments_settings, Routes.silentPaymentsSettings, condition: _isBtc),
- SettingsListItem("assets/new-ui/settings_row_icons/mweb.svg", S.current.litecoin_mweb_settings, Routes.mwebSettings, condition: _hasMweb),
+ SettingsListItem("assets/new-ui/settings_row_icons/lightning_username.svg", "Lightning ${S.current.username}", Routes.lightningUsernamePage, condition: _hasLightning),
+ SettingsListItem("assets/new-ui/settings_row_icons/wc.svg", S.current.walletConnect, Routes.walletConnectConnectionsListing, condition: _hasWalletConnect),
+ //SettingsListItem("assets/new-ui/settings_row_icons/silent-payments.svg", S.current.silent_payments_settings, Routes.silentPaymentsSettings, condition: _isBtc),
+ //SettingsListItem("assets/new-ui/settings_row_icons/mweb.svg", S.current.litecoin_mweb_settings, Routes.mwebSettings, condition: _hasMweb),
SettingsListItem("assets/new-ui/settings_row_icons/cupcake.svg", S.current.export_outputs, Routes.urqrAnimatedPage, routeArgs: {'export-outputs': 'export-outputs'}, condition: _isCupcake),
SettingsListItem("assets/new-ui/settings_row_icons/other.svg", S.current.other, Routes.otherSettingsPage),
]);
static SettingsSectionData appSettings =
- SettingsSectionData(S.current.app_settings, "assets/new-ui/app_settings.svg", [
+ SettingsSectionData(S.current.app_settings, "assets/new-ui/cake-setting.svg", [
SettingsListItem("assets/new-ui/settings_row_icons/connections.svg", S.current.connections, Routes.connectionSync),
// SettingsListItem("assets/new-ui/settings_row_icons/defaults.svg", "Defaults", ""),
SettingsListItem("assets/new-ui/settings_row_icons/display.svg", S.current.display, Routes.displaySettingsPage),
@@ -97,29 +102,26 @@ class SettingsMainPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
- Map<String, List<ListItem>> sections =
- Map.fromEntries(SettingsSectionData.all.map((section) => MapEntry(
- section.title,
- section.items
- .map((item) => item.condition(dashboardViewModel)
- ? ListItemRegularRow(
- keyValue: item.title,
- label: item.title,
- iconPath: item.iconPath,
- onTap: () {
- if (item.route.isNotEmpty) {
- if(item.requireAuth) {
- authService.authenticateAction(context,
- conditionToDetermineIfToUse2FA: item.use2fa(dashboardViewModel),
- route: item.route);
- } else {
- Navigator.of(context).pushNamed(item.route, arguments: item.routeArgs);
- }
- }
- })
- : null)
- .whereType<ListItem>()
- .toList())));
+ List<ListItem> buildItems(SettingsSectionData section) => section.items
+ .map((item) => item.condition(dashboardViewModel)
+ ? ListItemRegularRow(
+ keyValue: item.title,
+ label: item.title,
+ iconPath: item.iconPath,
+ onTap: () {
+ if (item.route.isNotEmpty) {
+ if (item.requireAuth) {
+ authService.authenticateAction(context,
+ conditionToDetermineIfToUse2FA: item.use2fa(dashboardViewModel),
+ route: item.route);
+ } else {
+ Navigator.of(context).pushNamed(item.route, arguments: item.routeArgs);
+ }
+ }
+ })
+ : null)
+ .whereType<ListItem>()
+ .toList();
return Container(
color: Theme.of(context).colorScheme.surface,
@@ -131,12 +133,31 @@ class SettingsMainPage extends StatelessWidget {
onTrailingPressed: () {},
),
Expanded(
- child: ListView(
- controller: ModalScrollController.of(context),
- children: [Padding(
- padding: const EdgeInsets.symmetric(vertical: 20.0, horizontal: 20.0),
- child: NewListSections(
- sections: sections,
+ child: ListView(controller: ModalScrollController.of(context), children: [
+ Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 20.0),
+ child: Column(
+ spacing: 16,
+ children: SettingsSectionData.all.expand((section) {
+ return [
+ if (section.titleIconPath.isNotEmpty)
+ Padding(
+ padding: const EdgeInsets.only(top: 8.0),
+ child: Row(
+ spacing: 8,
+ children: [
+ SvgPicture.asset(section.titleIconPath,
+ colorFilter: ColorFilter.mode(
+ Theme.of(context).colorScheme.onSurfaceVariant,
+ BlendMode.srcIn,
+ )),
+ Text(section.title, style: Theme.of(context).textTheme.titleMedium),
+ ],
+ ),
+ ),
+ NewListSections(sections: {section.title: buildItems(section)}),
+ ];
+ }).toList(),
),
),]
),
diff --git a/lib/new-ui/widgets/coins_page/top_bar_widget/sync_bar.dart b/lib/new-ui/widgets/coins_page/top_bar_widget/sync_bar.dart
index 2c55d97f..45e28bbb 100644
--- a/lib/new-ui/widgets/coins_page/top_bar_widget/sync_bar.dart
+++ b/lib/new-ui/widgets/coins_page/top_bar_widget/sync_bar.dart
@@ -1,12 +1,14 @@
import 'package:cake_wallet/core/sync_status_title.dart';
+import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/new-ui/widgets/coins_page/top_bar_widget/pulsing_dot.dart';
-import 'package:cake_wallet/routes.dart';
+import 'package:cake_wallet/src/screens/settings/manage_nodes_page.dart';
import 'package:cake_wallet/src/widgets/cake_image_widget.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cw_core/sync_status.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:flutter_svg/flutter_svg.dart';
+import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
class SyncBar extends StatelessWidget {
SyncBar({super.key, required this.dashboardViewModel, required this.isSyncHeavy});
@@ -62,7 +64,13 @@ class SyncBar extends StatelessWidget {
if (_showFullBar())
GestureDetector(
onTap: () {
- Navigator.of(context, rootNavigator: true).pushNamed(Routes.connectionSync);
+ CupertinoScaffold.showCupertinoModalBottomSheet(
+ context: context,
+ barrierColor: Colors.black.withAlpha(85),
+ builder: (context) => FractionallySizedBox(
+ child: Material(
+ child: getIt.get<ManageNodesPage>(param1: false),
+ )));
},
child: AnimatedSwitcher(
duration: Duration(milliseconds: 100),
@@ -162,7 +170,7 @@ class SyncBar extends StatelessWidget {
children.add(CakeImageWidget(imageUrl:
"assets/new-ui/mweb_sync.svg",
colorFilter:
- ColorFilter.mode(Theme.of(context).colorScheme.onSurfaceVariant, BlendMode.srcIn),
+ ColorFilter.mode(Theme.of(context).colorScheme.onSurfaceVariant, BlendMode.srcIn),
));
}
if (dashboardViewModel.hasSilentPayments) {
@@ -186,4 +194,4 @@ class SyncBar extends StatelessWidget {
bool _showDot() {
return !isSyncHeavy && progressStatuses.contains(dashboardViewModel.status.runtimeType);
}
-}
+}
\ No newline at end of file
diff --git a/lib/new-ui/widgets/modal_page_wrapper.dart b/lib/new-ui/widgets/modal_page_wrapper.dart
new file mode 100644
index 00000000..717b2078
--- /dev/null
+++ b/lib/new-ui/widgets/modal_page_wrapper.dart
@@ -0,0 +1,88 @@
+import 'package:cake_wallet/new-ui/widgets/modal_header.dart';
+import 'package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart';
+import 'package:flutter/material.dart';
+import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
+
+void nothing(){}
+
+class ModalPageWrapper extends StatelessWidget {
+ ModalPageWrapper(
+ {super.key,
+ required this.content,
+ required this.topBar,
+ this.header,
+ this.bottomContent,
+ this.horizontalPadding = 18.0,
+ this.verticalPadding = 72.0}) {
+ }
+
+ final Widget content;
+ final Widget? bottomContent;
+ final ModalTopBar topBar;
+ final ModalHeader? header;
+ final double horizontalPadding;
+ final double verticalPadding;
+
+ @override
+ Widget build(BuildContext context) {
+ const gradientSize = 84;
+
+ return Container(
+ color: Theme.of(context).colorScheme.surface,
+ child: Scaffold(
+ resizeToAvoidBottomInset: true,
+ body: Stack(
+ alignment: Alignment.topCenter,
+ children: [
+ Positioned.fill(
+ child: Padding(
+ padding: EdgeInsets.symmetric(horizontal: horizontalPadding),
+ child: CustomScrollView(
+ controller: ModalScrollController.of(context),
+ physics: ClampingScrollPhysics(),
+ slivers: [
+ SliverToBoxAdapter(child: SizedBox(height: verticalPadding)),
+ if (header != null) ...[
+ SliverToBoxAdapter(child: header),
+ SliverToBoxAdapter(child: SizedBox(height: 20)),
+ ],
+ SliverSafeArea(sliver: SliverToBoxAdapter(child: content)),
+ SliverToBoxAdapter(child: SizedBox(height: verticalPadding)),
+ ],
+ )
+ )),
+ if (bottomContent != null)
+ Positioned(
+ bottom: 12,
+ left: horizontalPadding,
+ right: horizontalPadding,
+ child: SafeArea(child: bottomContent!),
+ ),
+ Container(
+ height: (MediaQuery.of(context).padding.top + gradientSize),
+ decoration: BoxDecoration(
+ gradient: LinearGradient(
+ begin: Alignment.bottomCenter,
+ end: Alignment.topCenter,
+ colors: <Color>[
+ Theme.of(context).colorScheme.surface.withAlpha(5),
+ Theme.of(context).colorScheme.surface.withAlpha(25),
+ Theme.of(context).colorScheme.surface.withAlpha(50),
+ Theme.of(context).colorScheme.surface.withAlpha(100),
+ Theme.of(context).colorScheme.surface.withAlpha(150),
+ Theme.of(context).colorScheme.surface.withAlpha(200),
+ Theme.of(context).colorScheme.surface.withAlpha(235),
+ Theme.of(context).colorScheme.surface.withAlpha(255),
+ Theme.of(context).colorScheme.surface.withAlpha(255),
+ Theme.of(context).colorScheme.surface.withAlpha(255),
+ ],
+ ),
+ ),
+ ),
+ topBar,
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/new-ui/widgets/receive_page/receive_top_bar.dart b/lib/new-ui/widgets/receive_page/receive_top_bar.dart
index f92f00e7..9de76d6e 100644
--- a/lib/new-ui/widgets/receive_page/receive_top_bar.dart
+++ b/lib/new-ui/widgets/receive_page/receive_top_bar.dart
@@ -6,14 +6,14 @@ void nothing(){}
class ModalTopBar extends StatelessWidget {
ModalTopBar(
{super.key,
- required this.title,
+ required this.title,
this.subtitle,
- this.onLeadingPressed=nothing,
- this.onTrailingPressed=nothing,
- this.leadingIcon,
- this.trailingIcon,
- this.leadingWidget,
- this.trailingWidget}) {
+ this.onLeadingPressed=nothing,
+ this.onTrailingPressed=nothing,
+ this.leadingIcon,
+ this.trailingIcon,
+ this.leadingWidget,
+ this.trailingWidget}) {
if(leadingIcon != null && leadingWidget != null) {
throw Exception("Cannot have both leadingIcon and leadingWidget");
}
@@ -38,10 +38,10 @@ class ModalTopBar extends StatelessWidget {
return Padding(
padding: const EdgeInsets.all(18),
child: Stack(
- alignment: Alignment.center,
+ alignment: Alignment.topCenter,
children: [
- Align(
- alignment: Alignment.center,
+ Positioned(
+ top: 6,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
@@ -72,11 +72,11 @@ class ModalTopBar extends StatelessWidget {
if (leadingIcon != null || leadingWidget != null)
leadingIcon != null
? ModernButton(
- key: ValueKey(leadingIcon.hashCode),
- size: buttonSize,
- onPressed: onLeadingPressed,
- icon: leadingIcon!,
- iconColor: Theme.of(context).colorScheme.onSurfaceVariant)
+ key: ValueKey(leadingIcon.hashCode),
+ size: buttonSize,
+ onPressed: onLeadingPressed,
+ icon: leadingIcon!,
+ iconColor: Theme.of(context).colorScheme.onSurfaceVariant)
: leadingWidget!
else
Container(width: buttonSize),
@@ -85,10 +85,10 @@ class ModalTopBar extends StatelessWidget {
duration: const Duration(milliseconds: 200),
child: trailingIcon != null
? ModernButton(
- key: ValueKey(trailingIcon.hashCode),
- size: buttonSize,
- onPressed: onTrailingPressed,
- icon: trailingIcon!,)
+ key: ValueKey(trailingIcon.hashCode),
+ size: buttonSize,
+ onPressed: onTrailingPressed,
+ icon: trailingIcon!,)
: trailingWidget!,
)
else
@@ -99,4 +99,4 @@ class ModalTopBar extends StatelessWidget {
),
);
}
-}
+}
\ No newline at end of file
diff --git a/lib/src/screens/base_page.dart b/lib/src/screens/base_page.dart
index e5f3781e..4602c92b 100644
--- a/lib/src/screens/base_page.dart
+++ b/lib/src/screens/base_page.dart
@@ -47,6 +47,8 @@ abstract class BasePage extends StatelessWidget {
AppBarStyle get appBarStyle => AppBarStyle.regular;
+ bool get hideAppBar => false;
+
Widget Function(BuildContext, Widget)? get rootWrapper => null;
MaterialThemeBase get currentTheme => getIt.get<ThemeStore>().currentTheme;
@@ -191,24 +193,21 @@ abstract class BasePage extends StatelessWidget {
: null,
// color: Colors.grey[200],
),
- child: Padding(
- padding: const EdgeInsets.only(top:6.0),
- child: Scaffold(
- key: _scaffoldKey,
- backgroundColor: pageBackgroundColor(context),
- resizeToAvoidBottomInset: resizeToAvoidBottomInset,
- extendBodyBehindAppBar: extendBodyBehindAppBar,
- endDrawer: endDrawer,
- appBar: appBar(context),
- body: SafeArea(
- left: false,
- right: false,
- top: false,
- bottom: Platform.isAndroid,
- child: body(context),
- ),
- floatingActionButton: floatingActionButton(context),
+ child: Scaffold(
+ key: _scaffoldKey,
+ backgroundColor: pageBackgroundColor(context),
+ resizeToAvoidBottomInset: resizeToAvoidBottomInset,
+ extendBodyBehindAppBar: extendBodyBehindAppBar,
+ endDrawer: endDrawer,
+ appBar: hideAppBar ? null : appBar(context),
+ body: SafeArea(
+ left: false,
+ right: false,
+ top: false,
+ bottom: Platform.isAndroid,
+ child: body(context),
),
+ floatingActionButton: floatingActionButton(context),
),
);
},
diff --git a/lib/src/screens/nodes/widgets/node_form.dart b/lib/src/screens/nodes/widgets/node_form.dart
index 96ef7d6d..525252d8 100644
--- a/lib/src/screens/nodes/widgets/node_form.dart
+++ b/lib/src/screens/nodes/widgets/node_form.dart
@@ -5,6 +5,7 @@ import 'package:cake_wallet/entities/new_ui_entities/list_item/list_Item_checkbo
import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item_text_field.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/widgets/new_list_row/new_list_section.dart';
+import 'package:cake_wallet/utils/feature_flag.dart';
import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
@@ -140,6 +141,7 @@ class NodeFormState extends State<NodeForm> {
initialValue: vm.socksProxyAddress,
validator: SocksProxyNodeAddressValidator(),
),
+ if(FeatureFlag.isAutomaticNodeSwitchingEnabled)
ListItemCheckbox(
keyValue: vm.autoSwitchingUIKey,
label: S.current.enable_for_auto_switching,
diff --git a/lib/src/screens/nodes/widgets/node_list_row.dart b/lib/src/screens/nodes/widgets/node_list_row.dart
index 25d47775..2e43ad3f 100644
--- a/lib/src/screens/nodes/widgets/node_list_row.dart
+++ b/lib/src/screens/nodes/widgets/node_list_row.dart
@@ -7,11 +7,12 @@ import 'package:flutter/material.dart';
class NodeListRow extends StandardListRow {
NodeListRow(
{required String title,
+ String? subtitle,
required this.node,
required void Function(BuildContext context) onTap,
required bool isSelected,
required this.isPow})
- : super(title: title, onTap: onTap, isSelected: isSelected);
+ : super(title: title, onTap: onTap, isSelected: isSelected, subtitle: subtitle);
final Node node;
final bool isPow;
diff --git a/lib/src/screens/settings/connection_sync_page.dart b/lib/src/screens/settings/connection_sync_page.dart
index 61a88cf1..e609810f 100644
--- a/lib/src/screens/settings/connection_sync_page.dart
+++ b/lib/src/screens/settings/connection_sync_page.dart
@@ -1,119 +1,219 @@
import 'dart:io';
+import 'package:cake_wallet/entities/exchange_api_mode.dart';
+import 'package:cake_wallet/entities/fiat_api_mode.dart';
+import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item_regular_row.dart';
+import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item_selector.dart';
+import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item_toggle.dart';
import 'package:cake_wallet/generated/i18n.dart';
-import 'package:cake_wallet/reactions/wallet_connect.dart';
+import 'package:cake_wallet/new-ui/widgets/modal_header.dart';
+import 'package:cake_wallet/new-ui/widgets/modal_page_wrapper.dart';
+import 'package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
-import 'package:cake_wallet/src/screens/settings/widgets/settings_cell_with_arrow.dart';
-import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart';
-import 'package:cake_wallet/src/screens/settings/widgets/wallet_connect_button.dart';
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
+import 'package:cake_wallet/src/widgets/new_list_row/new_list_section.dart';
+import 'package:cake_wallet/src/widgets/picker.dart';
import 'package:cake_wallet/utils/feature_flag.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
-import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
+import 'package:cake_wallet/view_model/settings/connection_sync_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
class ConnectionSyncPage extends BasePage {
- ConnectionSyncPage(this.dashboardViewModel);
+ ConnectionSyncPage(this._connectionSyncViewModel);
@override
- String get title => S.current.connection_sync;
+ bool get hideAppBar => true;
- final DashboardViewModel dashboardViewModel;
+ final ConnectionSyncViewModel _connectionSyncViewModel;
@override
Widget body(BuildContext context) {
- return Container(
- padding: EdgeInsets.only(top: 10),
- child: Column(
+ return ModalPageWrapper(
+ topBar: ModalTopBar(
+ title: "",
+ leadingIcon: Icon(Icons.arrow_back_ios_new),
+ onLeadingPressed: () => Navigator.of(context).pop()),
+ header: ModalHeader(
+ iconPath: "assets/new-ui/settings_row_icons/connections.svg",
+ message: S.of(context).connections_desc,
+ title: S.of(context).connections),
+ content: Column(
mainAxisSize: MainAxisSize.min,
children: [
- SettingsCellWithArrow(
- title: S.current.reconnect,
- handler: (context) => _presentReconnectAlert(context),
- ),
- if (dashboardViewModel.hasRescan) ...[
- SettingsCellWithArrow(
- title: dashboardViewModel.hasSilentPayments
- ? S.current.silent_payments_scanning
- : S.current.rescan,
- handler: (context) => Navigator.of(context).pushNamed(Routes.rescan),
- ),
- ],
- SettingsCellWithArrow(
- title: S.current.manage_nodes,
- handler: (context) => Navigator.of(context).pushNamed(Routes.manageNodes),
- ),
- if (Platform.isAndroid && FeatureFlag.isBackgroundSyncEnabled) ...[
- SettingsCellWithArrow(
- title: S.current.background_sync,
- handler: (context) => Navigator.of(context).pushNamed(Routes.backgroundSync),
- ),
- ],
Observer(
- builder: (context) {
- if (!dashboardViewModel.hasPowNodes) return const SizedBox();
+ builder: (context) =>
+ NewListSections(
+ sections: {
+ "": [
+ if (FeatureFlag.isInAppTorEnabled)
+ ListItemToggle(
+ keyValue: "enable_builtin_tor",
+ label: S.of(context).enable_builtin_tor,
+ value: _connectionSyncViewModel.builtinTor,
+ onChanged: (val) {
+ _connectionSyncViewModel.setBuiltinTor(val, context);
+ }),
+ ListItemToggle(
+ keyValue: "disable_automatic_exchange_status_updates",
+ label: S.of(context).disable_automatic_exchange_status_updates,
+ value: _connectionSyncViewModel.disableAutomaticExchangeStatusUpdates,
+ onChanged: (val) {
+ _connectionSyncViewModel.setDisableAutomaticExchangeStatusUpdates(val);
+ }),
+ if (_connectionSyncViewModel.canUseBlinkProtection)
+ ListItemToggle(
+ keyValue: "can_use_blink_protection",
+ label: S.of(context).use_blink_protection,
+ value: _connectionSyncViewModel.useBlinkProtection,
+ onChanged: (val) {
+ _connectionSyncViewModel.setUseBlinkProtection(val);
+ }),
+ if (_connectionSyncViewModel.canUseEtherscan)
+ ListItemToggle(
+ keyValue: "can_use_etherscan",
+ label: S.of(context).etherscan_history,
+ value: _connectionSyncViewModel.useEtherscan,
+ onChanged: (val) {
+ _connectionSyncViewModel.setUseEtherscan(val);
+ }),
+ if (_connectionSyncViewModel.canUsePolygonScan)
+ ListItemToggle(
+ keyValue: "can_use_polygonscan",
+ label: S.of(context).polygonscan_history,
+ value: _connectionSyncViewModel.usePolygonScan,
+ onChanged: (val) {
+ _connectionSyncViewModel.setUsePolygonScan(val);
+ }),
+ if (_connectionSyncViewModel.canUseBaseScan)
+ ListItemToggle(
+ keyValue: "can_use_basescan",
+ label: S.of(context).basescan_history,
+ value: _connectionSyncViewModel.canUseBaseScan,
+ onChanged: (val) {
+ _connectionSyncViewModel.setUseBaseScan(val);
+ }),
+ if (_connectionSyncViewModel.canUseArbiScan)
+ ListItemToggle(
+ keyValue: "can_use_arbiscan",
+ label: S.of(context).arbiscan_history,
+ value: _connectionSyncViewModel.useArbiScan,
+ onChanged: (val) {
+ _connectionSyncViewModel.setUsePolygonScan(val);
+ }),
+ if (_connectionSyncViewModel.canUseBscScan)
+ ListItemToggle(
+ keyValue: "can_use_bscscan",
+ label: S.of(context).bscscan_history,
+ value: _connectionSyncViewModel.useBscScan,
+ onChanged: (val) {
+ _connectionSyncViewModel.setUseBscScan(val);
+ }),
+ if (_connectionSyncViewModel.canUseTronGrid)
+ ListItemToggle(
+ keyValue: "can_use_trongrid",
+ label: S.of(context).trongrid_history,
+ value: _connectionSyncViewModel.useTronGrid,
+ onChanged: (val) {
+ _connectionSyncViewModel.setUsePolygonScan(val);
+ }),
+ if (_connectionSyncViewModel.canUseMempoolFeeAPI)
+ ListItemToggle(
+ keyValue: "enable_mempool_api",
+ label: S.of(context).enable_mempool_api,
+ value: _connectionSyncViewModel.useMempoolFeeAPI,
+ onChanged: (bool isEnabled) async {
+ if (!isEnabled) {
+ final bool confirmation = await showPopUp<bool>(
+ context: context,
+ builder: (BuildContext context) {
+ return AlertWithTwoActions(
+ alertTitle: S.of(context).warning,
+ alertContent: S.of(context).disable_fee_api_warning,
+ rightButtonText: S.of(context).confirm,
+ leftButtonText: S.of(context).cancel,
+ actionRightButton: () => Navigator.of(context).pop(true),
+ actionLeftButton: () => Navigator.of(context).pop(false));
+ }) ??
+ false;
+ if (confirmation) {
+ _connectionSyncViewModel.setUseMempoolFeeAPI(isEnabled);
+ }
+ return;
+ }
+
+ _connectionSyncViewModel.setUseMempoolFeeAPI(isEnabled);
+ }),
+ if (Platform.isAndroid && FeatureFlag.isBackgroundSyncEnabled)
+ ListItemRegularRow(
+ keyValue: "background_sync",
+ label: S.of(context).background_sync,
+ onTap: () => Navigator.of(context).pushNamed(Routes.backgroundSync)
+ ),
+ if (_connectionSyncViewModel.hasPowNodes)
+ ListItemRegularRow(
+ keyValue: "manage_pow_nodes",
+ label: S.of(context).manage_pow_nodes,
+ onTap: () => Navigator.of(context).pushNamed(Routes.managePowNodes),
+ ),
+ ListItemSelector(
+ keyValue: "fiat_api",
+ label: S.of(context).fiat_api,
+ options: [_connectionSyncViewModel.fiatApiMode.title],
+ onTap: () async {
+ final items = FiatApiMode.all;
+
+ final selectedAtIndex =
+ items.indexOf(_connectionSyncViewModel.fiatApiMode);
+
+ await showPopUp<void>(
+ context: context,
+ builder: (_) => Picker(
+ items: items,
+ selectedAtIndex: selectedAtIndex,
+ mainAxisAlignment: MainAxisAlignment.start,
+ onItemSelected: (FiatApiMode fiatApiMode) {
+ _connectionSyncViewModel.setFiatMode(fiatApiMode);
+ },
+ isSeparated: false,
+ ),
+ );
+ }),
+ ListItemSelector(
+ keyValue: "swap",
+ label: S.of(context).swap,
+ options: [_connectionSyncViewModel.exchangeStatus.title],
+ onTap: () async {
+ final items = ExchangeApiMode.all;
- return Column(
- children: [
- SettingsCellWithArrow(
- title: S.current.manage_pow_nodes,
- handler: (context) => Navigator.of(context).pushNamed(Routes.managePowNodes),
- ),
- ],
- );
- },
+ final selectedAtIndex =
+ items.indexOf(_connectionSyncViewModel.exchangeStatus);
+
+ await showPopUp<void>(
+ context: context,
+ builder: (_) => Picker(
+ items: items,
+ selectedAtIndex: selectedAtIndex,
+ mainAxisAlignment: MainAxisAlignment.start,
+ onItemSelected: (ExchangeApiMode mode) {
+ _connectionSyncViewModel.setExchangeApiMode(mode);
+ },
+ isSeparated: false,
+ ),
+ );
+ }),
+ ListItemRegularRow(
+ keyValue: "domain_lookups",
+ label: S.of(context).domain_looks_up,
+ onTap: () => Navigator.of(context).pushNamed(Routes.domainLookupsPage)
+ ),
+ ],
+ }
+ )
),
- if (isWalletConnectCompatibleChain(dashboardViewModel.wallet.type) &&
- !dashboardViewModel.wallet.isHardwareWallet) ...[ // ToDo: Remove this line once WalletConnect is implemented
- WalletConnectTile(
- onTap: () => Navigator.of(context).pushNamed(Routes.walletConnectConnectionsListing),
- ),
- ],
- if (FeatureFlag.isInAppTorEnabled)
- Observer(builder: (context) {
- return SettingsSwitcherCell(
- leading: Container(
- padding: EdgeInsets.symmetric(horizontal: 4, vertical: 1),
- decoration: BoxDecoration(
- color: Colors.red.shade100,
- borderRadius: BorderRadius.circular(3),
- ),
- child: Text(
- 'Alpha',
- style: TextStyle(
- color: Colors.red.shade700,
- fontSize: 8,
- fontWeight: FontWeight.bold,
- ),
- ),
- ),
- title: S.current.enable_builtin_tor,
- value: dashboardViewModel.builtinTor,
- onValueChange: (_, bool value) => dashboardViewModel.setBuiltinTor(value, context),
- );
- }),
],
),
);
}
-
- Future<void> _presentReconnectAlert(BuildContext context) async {
- await showPopUp<void>(
- context: context,
- builder: (BuildContext context) {
- return AlertWithTwoActions(
- alertTitle: S.of(context).reconnection,
- alertContent: S.of(context).reconnect_alert_text,
- rightButtonText: S.of(context).ok,
- leftButtonText: S.of(context).cancel,
- actionRightButton: () async {
- Navigator.of(context).pop();
- await dashboardViewModel.reconnect();
- },
- actionLeftButton: () => Navigator.of(context).pop());
- },
- );
- }
}
diff --git a/lib/src/screens/settings/display_settings_page.dart b/lib/src/screens/settings/display_settings_page.dart
index 05a32262..c10efc9d 100644
--- a/lib/src/screens/settings/display_settings_page.dart
+++ b/lib/src/screens/settings/display_settings_page.dart
@@ -1,14 +1,18 @@
import 'package:cake_wallet/entities/bitcoin_amount_display_mode.dart';
import 'package:cake_wallet/entities/fiat_currency.dart';
import 'package:cake_wallet/entities/language_service.dart';
+import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item_regular_row.dart';
+import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item_selector.dart';
+import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item_toggle.dart';
import 'package:cake_wallet/entities/sync_status_display_mode.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart';
import 'package:cake_wallet/src/screens/settings/widgets/settings_choices_cell.dart';
-import 'package:cake_wallet/src/screens/settings/widgets/settings_picker_cell.dart';
-import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart';
import 'package:cake_wallet/src/screens/settings/widgets/settings_theme_choice.dart';
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
+import 'package:cake_wallet/src/widgets/new_list_row/new_list_section.dart';
+import 'package:cake_wallet/new-ui/widgets/modal_page_wrapper.dart';
+import 'package:cake_wallet/src/widgets/picker.dart';
import 'package:cake_wallet/src/widgets/standard_list.dart';
import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/utils/feature_flag.dart';
@@ -19,7 +23,6 @@ import 'package:cake_wallet/view_model/settings/display_settings_view_model.dart
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:image_picker/image_picker.dart';
-import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
class DisplaySettingsPage extends StatelessWidget {
DisplaySettingsPage(this._displaySettingsViewModel);
@@ -29,172 +32,228 @@ class DisplaySettingsPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
- return Container(
- color: Theme.of(context).colorScheme.surface,
- child: SafeArea(
- top: false,
- child: Column(
- children: [
- ModalTopBar(title: S.of(context).display_settings,leadingIcon: Icon(Icons.arrow_back_ios_new),onLeadingPressed: () => Navigator.of(context).pop()),
- Expanded(
- child: SingleChildScrollView(
- controller: ModalScrollController.of(context),
- physics: ClampingScrollPhysics(),
- child: Observer(builder: (_) {
- return Container(
- padding: EdgeInsets.only(top: 10),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- SettingsSwitcherCell(
- title: S.of(context).apps,
- value: _displaySettingsViewModel.shouldShowMarketPlaceInDashboard,
- onValueChange: (_, bool value) {
- _displaySettingsViewModel.setShouldShowMarketPlaceInDashbaord(value);
- },
- ),
- SettingsSwitcherCell(
- title: S.of(context).show_address_book_popup,
- value: _displaySettingsViewModel.showAddressBookPopup,
- onValueChange: (_, bool value) {
- _displaySettingsViewModel.setShowAddressBookPopup(value);
- },
- ),
- if (_displaySettingsViewModel.showZcashCardSetting)
- SettingsSwitcherCell(
- title: S.of(context).show_zcash_card,
- value: _displaySettingsViewModel.showZcashCard,
- onValueChange: (_, bool value) {
- _displaySettingsViewModel.setShowZcashCard(value);
- },
- ),
- SettingsPickerCell<SyncStatusDisplayMode>(
- title: S.current.sync_status_display_mode,
- items: SyncStatusDisplayMode.values.toList(),
- selectedItem: _displaySettingsViewModel.syncStatusDisplayMode,
- onItemSelected: (SyncStatusDisplayMode mode) =>
- _displaySettingsViewModel.setSyncStatusDisplayMode(mode),
- displayItem: (SyncStatusDisplayMode mode) => mode.title,
- isGridView: false,
- ),
- if (_displaySettingsViewModel.showDisplayAmountsInSatoshiSetting)
- SettingsPickerCell<BitcoinAmountDisplayMode>(
- title: S.of(context).bitcoin_amount_display,
- items: BitcoinAmountDisplayMode.all,
- selectedItem: _displaySettingsViewModel.displayAmountsInSatoshi,
- onItemSelected: _displaySettingsViewModel.setDisplayAmountsInSatoshi,
- displayItem: (mode) => mode.title,
- isGridView: false,
- ),
- //if (!isHaven) it does not work correctly
- if (!_displaySettingsViewModel.disabledFiatApiMode)
- SettingsPickerCell<FiatCurrency>(
- title: S.of(context).settings_currency,
- searchHintText: S.of(context).search_currency,
- items: FiatCurrency.all,
- selectedItem: _displaySettingsViewModel.fiatCurrency,
- onItemSelected: (FiatCurrency currency) =>
- _displaySettingsViewModel.setFiatCurrency(currency),
- images: FiatCurrency.all
- .map((e) => Image.asset("assets/images/flags/${e.countryCode}.png"))
- .toList(),
- isGridView: true,
- matchingCriteria: (FiatCurrency currency, String searchText) {
- return currency.title.toLowerCase().contains(searchText) ||
- currency.fullName.toLowerCase().contains(searchText);
- },
- ),
- SettingsPickerCell<String>(
- title: S.of(context).settings_change_language,
- searchHintText: S.of(context).search_language,
- items: LanguageService.list.keys.toList(),
- displayItem: (dynamic code) {
- return LanguageService.list[code] ?? '';
- },
- selectedItem: _displaySettingsViewModel.languageCode,
- onItemSelected: _displaySettingsViewModel.onLanguageSelected,
- images: LanguageService.list.keys
- .map((e) => Image.asset(
- "assets/images/flags/${LanguageService.localeCountryCode[e]}.png"))
- .toList(),
- matchingCriteria: (String code, String searchText) {
- return LanguageService.list[code]?.toLowerCase().contains(searchText) ?? false;
+ return ModalPageWrapper(
+ topBar: ModalTopBar(
+ title: S.of(context).display,
+ leadingIcon: Icon(Icons.arrow_back_ios_new),
+ onLeadingPressed: () => Navigator.of(context).pop(),
+ ),
+ content: Column(
+ spacing: 16,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ if (responsiveLayoutUtil.shouldRenderMobileUI &&
+ DeviceInfo.instance.isMobile) ...[
+ Padding(
+ padding: const EdgeInsets.only(left: 14, top: 14),
+ child: Text(
+ S.of(context).appearance,
+ style: Theme.of(context).textTheme.labelLarge?.copyWith(
+ height: 0.2,
+ color: Theme.of(context).colorScheme.onSurfaceVariant,
+ ),
+ ),
+ ),
+ Container(
+ decoration: ShapeDecoration(
+ color: Theme.of(context).colorScheme.surfaceContainerHigh,
+ shape: RoundedSuperellipseBorder(
+ borderRadius: BorderRadius.circular(18))),
+ child: Column(
+ children: [
+ SettingsChoicesCell(
+ ChoicesListItem<ThemeMode>(
+ title: "",
+ items: ThemeMode.values,
+ selectedItem: _displaySettingsViewModel.themeMode,
+ onItemSelected: (ThemeMode themeMode) =>
+ _displaySettingsViewModel.setThemeMode(themeMode),
+ displayItem: (ThemeMode themeMode) {
+ return themeMode.name[0].toUpperCase() +
+ themeMode.name.substring(1).toLowerCase();
},
),
-
- if (FeatureFlag.customBackgroundEnabled)
- StandardListRow(
- title: "Custom background",
- isSelected: false,
- onTap: (_) => _pickImage(context),
- ),
-
- if (responsiveLayoutUtil.shouldRenderMobileUI && DeviceInfo.instance.isMobile) ...[
- SizedBox(height: 24),
- Padding(
- padding: const EdgeInsets.only(left: 24),
- child: Text(
- S.current.appearance,
- style: Theme.of(context).textTheme.bodyMedium?.copyWith(
- fontWeight: FontWeight.w400,
- fontSize: 14,
- height: 22 / 14,
- color: Theme.of(context).colorScheme.onSurface,
- ),
+ useGenericColor: false,
+ padding: EdgeInsets.all(14),
+ ),
+ Container(
+ decoration: ShapeDecoration(
+ color: Theme.of(context).colorScheme.surfaceContainer,
+ shape: RoundedSuperellipseBorder(
+ borderRadius: BorderRadius.circular(18))),
+ child: Column(
+ children: [
+ Semantics(
+ label: S.of(context).color_theme,
+ child: SettingsThemeChoicesCell(_displaySettingsViewModel),
),
- ),
- SizedBox(height: 12),
- Container(
- margin: EdgeInsets.symmetric(horizontal: 20),
- decoration: BoxDecoration(
- color: Theme.of(context).colorScheme.surfaceContainer,
- borderRadius: BorderRadius.circular(16),
- ),
- child: Column(
- children: [
- SettingsChoicesCell(
- ChoicesListItem<ThemeMode>(
- title: "",
- items: ThemeMode.values,
- selectedItem: _displaySettingsViewModel.themeMode,
- onItemSelected: (ThemeMode themeMode) =>
- _displaySettingsViewModel.setThemeMode(themeMode),
- displayItem: (ThemeMode themeMode) {
- return themeMode.name[0].toUpperCase() +
- themeMode.name.substring(1).toLowerCase();
- },
- ),
- useGenericColor: false,
- padding: EdgeInsets.all(12),
+ ],
+ ),
+ ),
+ ],
+ ),
+ ),
+ ],
+ Observer(
+ builder: (_) => NewListSections(
+ sections: {
+ "": [
+ ListItemToggle(
+ keyValue: "apps",
+ label: S.of(context).apps,
+ value: _displaySettingsViewModel.shouldShowMarketPlaceInDashboard,
+ onChanged: (val) {
+ _displaySettingsViewModel.setShouldShowMarketPlaceInDashbaord(val);
+ }),
+ ListItemToggle(
+ keyValue: "display_settings_show_address_book_popup",
+ label: S.of(context).show_address_book_popup,
+ value: _displaySettingsViewModel.showAddressBookPopup,
+ onChanged: (val) {
+ _displaySettingsViewModel.setShowAddressBookPopup(val);
+ }),
+ ListItemToggle(
+ keyValue: "display_settings_disable_buy_button",
+ label: S.of(context).disable_buy,
+ value: _displaySettingsViewModel.disableTradeOption,
+ onChanged: (val) {
+ _displaySettingsViewModel.setDisableTradeOption(val);
+ }),
+ if (_displaySettingsViewModel.showZcashCardSetting)
+ ListItemToggle(
+ keyValue: "display_settings_show_zcashcard",
+ label: S.of(context).show_zcash_card,
+ value: _displaySettingsViewModel.showZcashCard,
+ onChanged: (val) {
+ _displaySettingsViewModel.setShowZcashCard(val);
+ }),
+ ListItemSelector(
+ keyValue: "display_settings_sync_status_display",
+ label: S.of(context).sync_status_display_mode,
+ options: [_displaySettingsViewModel.syncStatusDisplayMode.title],
+ onTap: () async {
+ final items = SyncStatusDisplayMode.values.toList();
+
+ final selectedAtIndex =
+ items.indexOf(_displaySettingsViewModel.syncStatusDisplayMode);
+
+ await showPopUp<void>(
+ context: context,
+ builder: (_) => Picker(
+ items: items,
+ selectedAtIndex: selectedAtIndex,
+ mainAxisAlignment: MainAxisAlignment.start,
+ onItemSelected: (SyncStatusDisplayMode mode) {
+ _displaySettingsViewModel.setSyncStatusDisplayMode(mode);
+ },
+ displayItem: (SyncStatusDisplayMode mode) => mode.title,
+ isSeparated: false,
+ ),
+ );
+ }),
+ if (_displaySettingsViewModel.showDisplayAmountsInSatoshiSetting)
+ ListItemRegularRow(
+ keyValue: "display_settings_bitcoin_amount_display",
+ label: S.of(context).bitcoin_amount_display,
+ trailingText: _displaySettingsViewModel.displayAmountsInSatoshi.title,
+ onTap: () async {
+ final items = BitcoinAmountDisplayMode.all;
+
+ final selectedAtIndex =
+ items.indexOf(_displaySettingsViewModel.displayAmountsInSatoshi);
+
+ await showPopUp<void>(
+ context: context,
+ builder: (_) => Picker(
+ items: items,
+ selectedAtIndex: selectedAtIndex,
+ mainAxisAlignment: MainAxisAlignment.start,
+ onItemSelected: _displaySettingsViewModel.setDisplayAmountsInSatoshi,
+ displayItem: (BitcoinAmountDisplayMode mode) => mode.title,
+ isSeparated: false,
),
- Container(
- decoration: BoxDecoration(
- color: Theme.of(context).colorScheme.surfaceContainerHigh,
- borderRadius: BorderRadius.circular(16),
- ),
- child: Column(
- children: [
- Semantics(
- label: S.of(context).color_theme,
- child: SettingsThemeChoicesCell(_displaySettingsViewModel),
- ),
- ],
- ),
+ );
+ }),
+ if (!_displaySettingsViewModel.disabledFiatApiMode)
+ ListItemSelector(
+ keyValue: "display_settings_fiat_currency",
+ label: S.of(context).settings_currency,
+ options: [_displaySettingsViewModel.fiatCurrency.title],
+ onTap: () async {
+ final items = FiatCurrency.all;
+
+ final selectedAtIndex =
+ items.indexOf(_displaySettingsViewModel.fiatCurrency);
+
+ await showPopUp<void>(
+ context: context,
+ builder: (_) => Picker(
+ items: items,
+ selectedAtIndex: selectedAtIndex,
+ mainAxisAlignment: MainAxisAlignment.start,
+ onItemSelected: (FiatCurrency currency) {
+ _displaySettingsViewModel.setFiatCurrency(currency);
+ },
+ images: FiatCurrency.all
+ .map((e) => Image.asset("assets/images/flags/${e.countryCode}.png"))
+ .toList(),
+ hintText: S.of(context).search_currency,
+ isGridView: true,
+ matchingCriteria: (FiatCurrency currency, String searchText) {
+ return currency.title.toLowerCase().contains(searchText) ||
+ currency.fullName.toLowerCase().contains(searchText);
+ },
+ isSeparated: false,
+
),
- ],
- ),
- ),
- ],
- ],
- ),
- );
- }),
+ );
+ }),
+ ListItemSelector(
+ keyValue: "display_settings_language",
+ label: S.of(context).settings_change_language,
+ options: [LanguageService.list[_displaySettingsViewModel.languageCode] ?? ''],
+ onTap: () async {
+ final items = LanguageService.list.keys.toList();
+
+ final selectedAtIndex =
+ items.indexOf(_displaySettingsViewModel.languageCode);
+
+ await showPopUp<void>(
+ context: context,
+ builder: (_) => Picker(
+ displayItem: (dynamic code) {
+ return LanguageService.list[code] ?? '';
+ },
+ items: items,
+ selectedAtIndex: selectedAtIndex,
+ mainAxisAlignment: MainAxisAlignment.start,
+ onItemSelected: _displaySettingsViewModel.onLanguageSelected,
+ images: LanguageService.list.keys
+ .map((e) => Image.asset(
+ "assets/images/flags/${LanguageService.localeCountryCode[e]}.png"))
+ .toList(),
+ hintText: S.of(context).search_language,
+ matchingCriteria: (String code, String searchText) {
+ return LanguageService.list[code]?.toLowerCase().contains(searchText) ?? false;
+ },
+ isSeparated: true,
+
+ ),
+ );
+ }),
+ ],
+ },
+ ),
),
- ),
- ],
- ),
- ),
- );
+ if (FeatureFlag.customBackgroundEnabled)
+ StandardListRow(
+ title: "Custom background",
+ isSelected: false,
+ onTap: (_) => _pickImage(context),
+ ),
+ ],
+ ),
+ );
}
// Function to pick an image from the gallery
diff --git a/lib/src/screens/settings/domain_lookups_page.dart b/lib/src/screens/settings/domain_lookups_page.dart
index ed591643..b566892a 100644
--- a/lib/src/screens/settings/domain_lookups_page.dart
+++ b/lib/src/screens/settings/domain_lookups_page.dart
@@ -1,17 +1,17 @@
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart';
-import 'package:cake_wallet/view_model/settings/privacy_settings_view_model.dart';
+import 'package:cake_wallet/view_model/settings/connection_sync_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
class DomainLookupsPage extends BasePage {
- DomainLookupsPage(this._privacySettingsViewModel);
+ DomainLookupsPage(this._connectionsSyncViewModel);
@override
String get title => S.current.domain_looks_up;
- final PrivacySettingsViewModel _privacySettingsViewModel;
+ final ConnectionSyncViewModel _connectionsSyncViewModel;
@override
Widget body(BuildContext context) {
@@ -23,36 +23,36 @@ class DomainLookupsPage extends BasePage {
children: [
SettingsSwitcherCell(
title: 'Twitter',
- value: _privacySettingsViewModel.lookupTwitter,
- onValueChange: (_, bool value) => _privacySettingsViewModel.setLookupsTwitter(value)),
+ value: _connectionsSyncViewModel.lookupTwitter,
+ onValueChange: (_, bool value) => _connectionsSyncViewModel.setLookupsTwitter(value)),
SettingsSwitcherCell(
title: 'Mastodon',
- value: _privacySettingsViewModel.looksUpMastodon,
- onValueChange: (_, bool value) => _privacySettingsViewModel.setLookupsMastodon(value)),
+ value: _connectionsSyncViewModel.looksUpMastodon,
+ onValueChange: (_, bool value) => _connectionsSyncViewModel.setLookupsMastodon(value)),
SettingsSwitcherCell(
title: 'Yat service',
- value: _privacySettingsViewModel.looksUpYatService,
- onValueChange: (_, bool value) => _privacySettingsViewModel.setLookupsYatService(value)),
+ value: _connectionsSyncViewModel.looksUpYatService,
+ onValueChange: (_, bool value) => _connectionsSyncViewModel.setLookupsYatService(value)),
SettingsSwitcherCell(
title: 'Unstoppable Domains',
- value: _privacySettingsViewModel.looksUpUnstoppableDomains,
- onValueChange: (_, bool value) => _privacySettingsViewModel.setLookupsUnstoppableDomains(value)),
+ value: _connectionsSyncViewModel.looksUpUnstoppableDomains,
+ onValueChange: (_, bool value) => _connectionsSyncViewModel.setLookupsUnstoppableDomains(value)),
SettingsSwitcherCell(
title: 'OpenAlias',
- value: _privacySettingsViewModel.looksUpOpenAlias,
- onValueChange: (_, bool value) => _privacySettingsViewModel.setLookupsOpenAlias(value)),
+ value: _connectionsSyncViewModel.looksUpOpenAlias,
+ onValueChange: (_, bool value) => _connectionsSyncViewModel.setLookupsOpenAlias(value)),
SettingsSwitcherCell(
title: 'Ethereum Name Service',
- value: _privacySettingsViewModel.looksUpENS,
- onValueChange: (_, bool value) => _privacySettingsViewModel.setLookupsENS(value)),
+ value: _connectionsSyncViewModel.looksUpENS,
+ onValueChange: (_, bool value) => _connectionsSyncViewModel.setLookupsENS(value)),
SettingsSwitcherCell(
title: '.well-known',
- value: _privacySettingsViewModel.looksUpWellKnown,
- onValueChange: (_, bool value) => _privacySettingsViewModel.setLookupsWellKnown(value)),
+ value: _connectionsSyncViewModel.looksUpWellKnown,
+ onValueChange: (_, bool value) => _connectionsSyncViewModel.setLookupsWellKnown(value)),
SettingsSwitcherCell(
title: 'Zano Aliases',
- value: _privacySettingsViewModel.lookupsZanoAlias,
- onValueChange: (_, bool value) => _privacySettingsViewModel.setLookupsZanoAlias(value)),
+ value: _connectionsSyncViewModel.lookupsZanoAlias,
+ onValueChange: (_, bool value) => _connectionsSyncViewModel.setLookupsZanoAlias(value)),
//if (!isHaven) it does not work correctly
],
diff --git a/lib/src/screens/settings/manage_nodes_page.dart b/lib/src/screens/settings/manage_nodes_page.dart
index b96ea875..c1cd9252 100644
--- a/lib/src/screens/settings/manage_nodes_page.dart
+++ b/lib/src/screens/settings/manage_nodes_page.dart
@@ -1,4 +1,8 @@
import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/new-ui/widgets/modal_header.dart';
+import 'package:cake_wallet/new-ui/widgets/modal_page_wrapper.dart';
+import 'package:cake_wallet/new-ui/widgets/modern_button.dart';
+import 'package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/nodes/widgets/node_list_row.dart';
@@ -7,6 +11,7 @@ import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
import 'package:cake_wallet/src/widgets/standard_list.dart';
import 'package:cake_wallet/utils/feature_flag.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
+import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cake_wallet/view_model/node_list/node_list_view_model.dart';
import 'package:cake_wallet/view_model/node_list/pow_node_list_view_model.dart';
import 'package:flutter/material.dart';
@@ -14,30 +19,46 @@ import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
class ManageNodesPage extends BasePage {
- ManageNodesPage(this.isPow, {this.nodeListViewModel, this.powNodeListViewModel})
+ ManageNodesPage(this.isPow, {this.nodeListViewModel, this.powNodeListViewModel, this.dashboardViewModel})
: assert((isPow && powNodeListViewModel != null) || (!isPow && nodeListViewModel != null)),
assert(powNodeListViewModel == null || nodeListViewModel == null);
+ final DashboardViewModel? dashboardViewModel;
final NodeListViewModel? nodeListViewModel;
final PowNodeListViewModel? powNodeListViewModel;
final bool isPow;
+ @override
+ bool get hideAppBar => true;
+
@override
String get title => S.current.manage_nodes;
@override
Widget body(BuildContext context) {
- return Padding(
- padding: EdgeInsets.only(top: 10),
- child: Column(
+ return ModalPageWrapper(
+ horizontalPadding: 0,
+ topBar: ModalTopBar(
+ title: S.of(context).manage_nodes,
+ leadingIcon: Icon(Icons.arrow_back_ios_new),
+ onLeadingPressed: () => Navigator.of(context).pop(),
+ trailingWidget: Row(
+ spacing: 8,
+ children: [
+ if (dashboardViewModel?.hasRescan ?? true)
+ ModernButton(
+ size: 36,
+ icon: Icon(Icons.history),
+ onPressed: () => Navigator.of(context).pushNamed(Routes.rescan)),
+ ModernButton(
+ size: 36,
+ icon: Icon(Icons.add),
+ onPressed: () => Navigator.of(context).pushNamed(isPow ? Routes.newPowNode : Routes.newNode))
+ ],
+ ),
+ ),
+ content: Column(
children: [
- Semantics(
- button: true,
- child: NodeHeaderListRow(
- title: S.of(context).add_new_node,
- onTap: (_) async => await Navigator.of(context).pushNamed(isPow ? Routes.newPowNode : Routes.newNode),
- ),
- ),
if (FeatureFlag.isAutomaticNodeSwitchingEnabled)
Observer(
builder: (_) => SettingsSwitcherCell(
@@ -60,32 +81,34 @@ class ManageNodesPage extends BasePage {
builder: (BuildContext context) {
int itemsCount =
nodeListViewModel?.nodes.length ?? powNodeListViewModel!.nodes.length;
- return Flexible(
- child: SectionStandardList(
- scrollController: ModalScrollController.of(context),
- sectionCount: 1,
- dividerPadding: EdgeInsets.symmetric(horizontal: 24),
- itemCounter: (int sectionIndex) => itemsCount,
- itemBuilder: (_, index) {
- return Observer(
- builder: (context) {
- final node =
- nodeListViewModel?.nodes[index] ?? powNodeListViewModel!.nodes[index];
- late bool isSelected;
- if (isPow) {
- isSelected = node.keyIndex == powNodeListViewModel!.currentNode.keyIndex;
- } else {
- isSelected = node.keyIndex == nodeListViewModel!.currentNode.keyIndex;
- }
- final nodeListRow = NodeListRow(
- title: node.uriRaw,
- node: node,
- isSelected: isSelected,
- isPow: isPow,
- onTap: (_) async {
- if (isSelected) {
- return;
- }
+ return SectionStandardList(
+ scrollController: ModalScrollController.of(context),
+ sectionCount: 1,
+ shrinkWrap: true,
+ physics: NeverScrollableScrollPhysics(),
+ dividerPadding: EdgeInsets.symmetric(horizontal: 24),
+ itemCounter: (int sectionIndex) => itemsCount,
+ itemBuilder: (_, index) {
+ return Observer(
+ builder: (context) {
+ final node =
+ nodeListViewModel?.nodes[index] ?? powNodeListViewModel!.nodes[index];
+ late bool isSelected;
+ if (isPow) {
+ isSelected = node.keyIndex == powNodeListViewModel!.currentNode.keyIndex;
+ } else {
+ isSelected = node.keyIndex == nodeListViewModel!.currentNode.keyIndex;
+ }
+ final nodeListRow = NodeListRow(
+ title: node.uriRaw,
+ subtitle: node.label!,
+ node: node,
+ isSelected: isSelected,
+ isPow: isPow,
+ onTap: (_) async {
+ if (isSelected) {
+ return;
+ }
await showPopUp<void>(
context: context,
@@ -110,11 +133,10 @@ class ManageNodesPage extends BasePage {
);
},
);
- return nodeListRow;
- },
- );
- },
- ),
+ return nodeListRow;
+ },
+ );
+ },
);
},
),
@@ -122,4 +144,21 @@ class ManageNodesPage extends BasePage {
),
);
}
+ Future<void> _presentReconnectAlert(BuildContext context) async {
+ await showPopUp<void>(
+ context: context,
+ builder: (BuildContext context) {
+ return AlertWithTwoActions(
+ alertTitle: S.of(context).reconnection,
+ alertContent: S.of(context).reconnect_alert_text,
+ rightButtonText: S.of(context).ok,
+ leftButtonText: S.of(context).cancel,
+ actionRightButton: () async {
+ Navigator.of(context).pop();
+ await dashboardViewModel!.reconnect();
+ },
+ actionLeftButton: () => Navigator.of(context).pop());
+ },
+ );
+ }
}
diff --git a/lib/src/screens/settings/mweb_node_page.dart b/lib/src/screens/settings/mweb_node_page.dart
index 3f153f42..32ba6886 100644
--- a/lib/src/screens/settings/mweb_node_page.dart
+++ b/lib/src/screens/settings/mweb_node_page.dart
@@ -1,56 +1,64 @@
-import 'package:cake_wallet/src/screens/base_page.dart';
-import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
+import 'package:cake_wallet/core/node_address_validator.dart';
+import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item_text_field.dart';
+import 'package:cake_wallet/new-ui/widgets/modal_page_wrapper.dart';
+import 'package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart';
+import 'package:cake_wallet/src/widgets/new_list_row/new_list_section.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/view_model/settings/mweb_settings_view_model.dart';
import 'package:flutter/material.dart';
-import 'package:flutter_mobx/flutter_mobx.dart';
-
-class MwebNodePage extends BasePage {
- MwebNodePage(this.mwebSettingsViewModelBase)
- : _nodeUriController = TextEditingController(text: mwebSettingsViewModelBase.mwebNodeUri),
- super();
+class MwebNodePage extends StatefulWidget {
+ const MwebNodePage(this.mwebSettingsViewModelBase, {super.key});
final MwebSettingsViewModelBase mwebSettingsViewModelBase;
- final TextEditingController _nodeUriController;
@override
- String get title => S.current.litecoin_mweb_node;
+ State<MwebNodePage> createState() => _MwebNodePageState();
+}
+
+class _MwebNodePageState extends State<MwebNodePage> {
+ late final TextEditingController _nodeUriController =
+ TextEditingController(text: widget.mwebSettingsViewModelBase.mwebNodeUri);
+
+ @override
+ void dispose() {
+ _nodeUriController.dispose();
+ super.dispose();
+ }
@override
- Widget body(BuildContext context) {
- return Stack(
- fit: StackFit.expand,
- children: [
- Container(
- padding: EdgeInsets.symmetric(horizontal: 24),
- child: Row(
- children: <Widget>[
- Expanded(
- child: BaseTextFormField(controller: _nodeUriController),
- )
- ],
- ),
+ Widget build(BuildContext context) {
+ return ModalPageWrapper(
+ topBar: ModalTopBar(
+ title: S.current.litecoin_mweb_settings,
+ onLeadingPressed: Navigator.of(context).pop,
+ leadingIcon: Icon(Icons.arrow_back_ios_new)),
+ content: Container(
+ child: NewListSections(
+ controllers: {
+ widget.mwebSettingsViewModelBase.mwebNodeUri: _nodeUriController,
+ },
+ sections: {
+ 'main': [
+ ListItemTextField(
+ keyValue: widget.mwebSettingsViewModelBase.mwebNodeUri,
+ label: S.current.node_address,
+ validator: NodePathValidator(),
+ ),
+ ]
+ }),
),
- Positioned(
- child: Observer(
- builder: (_) => LoadingPrimaryButton(
- onPressed: () => save(context),
- text: S.of(context).save,
- color: Theme.of(context).colorScheme.primary,
- textColor: Theme.of(context).colorScheme.onPrimary,
- ),
- ),
- bottom: 24,
- left: 24,
- right: 24,
- )
- ],
+ bottomContent: LoadingPrimaryButton(
+ onPressed: () => save(context),
+ text: S.of(context).save,
+ color: Theme.of(context).colorScheme.primary,
+ textColor: Theme.of(context).colorScheme.onPrimary,
+ ),
);
}
void save(BuildContext context) {
- mwebSettingsViewModelBase.setMwebNodeUri(_nodeUriController.text);
+ widget.mwebSettingsViewModelBase.setMwebNodeUri(_nodeUriController.text);
Navigator.pop(context);
}
}
diff --git a/lib/src/screens/settings/other_settings_page.dart b/lib/src/screens/settings/other_settings_page.dart
index fb1059ec..78456f69 100644
--- a/lib/src/screens/settings/other_settings_page.dart
+++ b/lib/src/screens/settings/other_settings_page.dart
@@ -1,21 +1,24 @@
import 'package:cake_wallet/bitcoin/bitcoin.dart';
+import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item_regular_row.dart';
+import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item_selector.dart';
import 'package:cake_wallet/entities/priority_for_wallet_type.dart';
import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/new-ui/widgets/modal_page_wrapper.dart';
+import 'package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/dev/moneroc_cache_debug.dart';
-import 'package:cake_wallet/src/screens/settings/widgets/setting_priority_picker_cell.dart';
-import 'package:cake_wallet/src/screens/settings/widgets/settings_cell_with_arrow.dart';
-import 'package:cake_wallet/src/screens/settings/widgets/settings_picker_cell.dart';
-import 'package:cake_wallet/src/screens/settings/widgets/settings_version_cell.dart';
+import 'package:cake_wallet/src/widgets/new_list_row/new_list_section.dart';
+import 'package:cake_wallet/src/widgets/picker.dart';
import 'package:cake_wallet/utils/feature_flag.dart';
import 'package:cake_wallet/utils/share_util.dart';
+import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/settings/other_settings_view_model.dart';
import 'package:cw_core/wallet_info.dart';
+import 'package:cw_core/transaction_priority.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:cw_core/db/sqlite.dart';
import 'package:flutter/material.dart';
-import 'package:flutter_mobx/flutter_mobx.dart';
class OtherSettingsPage extends BasePage {
OtherSettingsPage(this._otherSettingsViewModel) {
@@ -25,164 +28,206 @@ class OtherSettingsPage extends BasePage {
}
@override
- String get title => S.current.other_settings;
+ bool get hideAppBar => true;
final OtherSettingsViewModel _otherSettingsViewModel;
+
@override
- Widget body(BuildContext context) => Observer(
- builder: (_) => Container(
- padding: EdgeInsets.only(top: 10),
- child: Column(
- children: [
- Expanded(
- child: SingleChildScrollView(
- child: Column(
- children: [
- if (_otherSettingsViewModel.displayTransactionPriority)
- _otherSettingsViewModel.walletType == WalletType.bitcoin
- ? SettingsPriorityPickerCell(
- title: S.current.settings_fee_priority,
- items: priorityForWalletType(_otherSettingsViewModel.walletType),
- displayItem: _otherSettingsViewModel.getDisplayBitcoinPriority,
- selectedItem: _otherSettingsViewModel.transactionPriority,
- customItemIndex: _otherSettingsViewModel.customPriorityItemIndex,
- onItemSelected: _otherSettingsViewModel.onDisplayBitcoinPrioritySelected,
- customValue: _otherSettingsViewModel.customBitcoinFeeRate,
- maxValue: _otherSettingsViewModel.maxCustomFeeRate?.toDouble(),
- )
- : SettingsPickerCell(
- title: S.current.settings_fee_priority,
- items: priorityForWalletType(_otherSettingsViewModel.walletType),
- displayItem: _otherSettingsViewModel.getDisplayPriority,
- selectedItem: _otherSettingsViewModel.transactionPriority,
- onItemSelected: _otherSettingsViewModel.onDisplayPrioritySelected,
- ),
- if (_otherSettingsViewModel.changeRepresentativeEnabled)
- SettingsCellWithArrow(
- title: S.current.change_rep,
- handler: (context) => Navigator.of(context).pushNamed(Routes.changeRep),
- ),
- if (_otherSettingsViewModel.changeHardwareWalletTypeEnabled)
- SettingsCellWithArrow(
- title: "Hardware wallet manufacturer",
- handler: (context) => Navigator.of(context)
- .pushNamed(Routes.restoreWalletFromHardwareWallet, arguments: {
- "showUnavailable": false,
- "availableHardwareWalletTypes": [
- HardwareWalletType.cupcake,
- HardwareWalletType.coldcard,
- HardwareWalletType.seedsigner,
- ],
- "onSelect": (BuildContext context, HardwareWalletType hwType) async {
- await _otherSettingsViewModel.onHardwareWalletTypeChanged(hwType);
- Navigator.pop(context);
+ Widget body(BuildContext context) {
+ return ModalPageWrapper(
+ topBar: ModalTopBar(
+ title: S.of(context).other,
+ leadingIcon: Icon(Icons.arrow_back_ios_new),
+ onLeadingPressed: () => Navigator.of(context).pop(),
+ ),
+ // header: ModalHeader(
+ // iconPath: "assets/new-ui/settings_row_icons/other.svg",
+ // message: "Other settings",
+ // title: S.of(context).other_settings),
+ content: NewListSections(
+ sections: {
+ "": [
+ if (_otherSettingsViewModel.displayTransactionPriority)
+ _otherSettingsViewModel.walletType == WalletType.bitcoin
+ ? ListItemSelector(
+ keyValue: "fee_priority",
+ label: S.of(context).settings_fee_priority,
+ options: [_otherSettingsViewModel.transactionPriority.title],
+ onTap: () async {
+
+ final items = priorityForWalletType(_otherSettingsViewModel.walletType);
+
+ var selectedAtIndex = items.indexOf(_otherSettingsViewModel.transactionPriority);
+ double sliderValue = _otherSettingsViewModel.customBitcoinFeeRate ?? 0.0;
+
+ await showPopUp<void>(
+ context: context,
+ builder: (BuildContext context) {
+ return StatefulBuilder(
+ builder: (BuildContext context, StateSetter setState) {
+ return Picker(
+ items: items,
+ displayItem: (TransactionPriority item) => _otherSettingsViewModel.getDisplayBitcoinPriority(item, sliderValue.round()),
+ selectedAtIndex: selectedAtIndex,
+ customItemIndex: _otherSettingsViewModel.customPriorityItemIndex,
+ maxValue: _otherSettingsViewModel.maxCustomFeeRate?.toDouble(),
+ headerEnabled: false,
+ closeOnItemSelected: false,
+ mainAxisAlignment: MainAxisAlignment.center,
+ sliderValue: sliderValue,
+ onSliderChanged: (double newValue) =>
+ setState(() => sliderValue = newValue),
+ onItemSelected: (TransactionPriority priority) {
+ setState(() => selectedAtIndex = items.indexOf(priority));
+ _otherSettingsViewModel.onDisplayBitcoinPrioritySelected.call(priority, sliderValue);
},
- }),
- ),
- if (_otherSettingsViewModel.walletType == WalletType.bitcoin) ...[
- SettingsCellWithArrow(
- title: S.of(context).export_lightning_logs,
- handler: onExportLNLog,
- ),
- SettingsCellWithArrow(
- title: S.of(context).export_payjoin_logs,
- handler: onExportPJLog,
- ),
- ],
- SettingsCellWithArrow(
- title: S.current.settings_terms_and_conditions,
- handler: (context) => Navigator.of(context).pushNamed(Routes.readDisclaimer),
- ),
- if (FeatureFlag.hasDevOptions &&
- _otherSettingsViewModel.walletType == WalletType.monero)
- SettingsCellWithArrow(
- title: '[dev] monero background sync',
- handler: (context) =>
- Navigator.of(context).pushNamed(Routes.devMoneroBackgroundSync),
- ),
- if (FeatureFlag.hasDevOptions &&
- [WalletType.monero, WalletType.wownero, WalletType.zano]
- .contains(_otherSettingsViewModel.walletType))
- SettingsCellWithArrow(
- title: '[dev] xmr call profiler',
- handler: (context) =>
- Navigator.of(context).pushNamed(Routes.devMoneroCallProfiler),
- ),
- if (FeatureFlag.hasDevOptions &&
- [WalletType.monero].contains(_otherSettingsViewModel.walletType))
- SettingsCellWithArrow(
- title: '[dev] xmr wallet cache debug',
- handler: (context) =>
- Navigator.of(context).pushNamed(Routes.devMoneroWalletCacheDebug),
- ),
- if (FeatureFlag.hasDevOptions)
- SettingsCellWithArrow(
- title: '[dev] shared preferences',
- handler: (context) =>
- Navigator.of(context).pushNamed(Routes.devSharedPreferences),
- ),
- if (FeatureFlag.hasDevOptions)
- SettingsCellWithArrow(
- title: '[dev] secure storage preferences',
- handler: (context) =>
- Navigator.of(context).pushNamed(Routes.devSecurePreferences),
- ),
- if (FeatureFlag.hasDevOptions)
- SettingsCellWithArrow(
- title: '[dev] background sync logs',
- handler: (context) =>
- Navigator.of(context).pushNamed(Routes.devBackgroundSyncLogs),
- ),
- if (FeatureFlag.hasDevOptions)
- SettingsCellWithArrow(
- title: '[dev] socket health logs',
- handler: (context) => Navigator.of(context).pushNamed(Routes.devSocketHealthLogs),
- ),
- if (FeatureFlag.hasDevOptions)
- SettingsCellWithArrow(
- title: '[dev] network requests logs',
- handler: (context) => Navigator.of(context).pushNamed(Routes.devNetworkRequests),
- ),
- if (FeatureFlag.hasDevOptions)
- SettingsCellWithArrow(
- title: '[dev] exchange provider logs',
- handler: (context) =>
- Navigator.of(context).pushNamed(Routes.devExchangeProviderLogs),
- ),
- if (FeatureFlag.hasDevOptions)
- SettingsCellWithArrow(
- title: '[dev] *QR tools',
- handler: (context) => Navigator.of(context).pushNamed(Routes.devQRTools),
- ),
- if (FeatureFlag.hasDevOptions)
- SettingsCellWithArrow(
- title: '[dev] exchange provider logs',
- handler: (BuildContext context) =>
- Navigator.of(context).pushNamed(Routes.devExchangeProviderLogs),
- ),
- if (FeatureFlag.hasDevOptions)
- SettingsCellWithArrow(
- title: '[dev] browse sqlite db',
- handler: (BuildContext context) async {
- final data = await dumpDb();
- Navigator.of(context).push(
- MaterialPageRoute(builder: (context) => JsonExplorerPage(data: data, title: 'sqlite db')),
- );
- }
- ),
- ],
+ );
+ },
+ );
+ },
+ );
+ _otherSettingsViewModel.onDisplayBitcoinPrioritySelected.call(items[selectedAtIndex], sliderValue);
+ }
+ )
+ : ListItemSelector(
+ keyValue: "fee_priority",
+ label: S.of(context).settings_fee_priority,
+ options: [_otherSettingsViewModel.transactionPriority.title],
+ onTap: () async {
+ final selectedAtIndex = priorityForWalletType(_otherSettingsViewModel.walletType).indexOf(_otherSettingsViewModel.transactionPriority,);
+
+ await showPopUp<void>(
+ context: context,
+ builder: (_) => Picker(
+ items: priorityForWalletType(_otherSettingsViewModel.walletType),
+ displayItem: _otherSettingsViewModel.getDisplayPriority,
+ selectedAtIndex: selectedAtIndex,
+ mainAxisAlignment: MainAxisAlignment.start,
+ onItemSelected: (TransactionPriority item) => _otherSettingsViewModel.onDisplayBitcoinPrioritySelected.call(item, 0),
+ isSeparated: false,
),
- ),
+ );
+ },
+ ),
+ if(_otherSettingsViewModel.changeRepresentativeEnabled)
+ ListItemRegularRow(
+ keyValue: "change_rep",
+ label: S.of(context).change_rep,
+ onTap: () => Navigator.of(context).pushNamed(Routes.changeRep)
+ ),
+ if (_otherSettingsViewModel.changeHardwareWalletTypeEnabled)
+ ListItemRegularRow(
+ keyValue: "hardware_wallet_manufacturer",
+ label: "Hardware wallet manufacturer",
+ onTap: () => Navigator.of(context)
+ .pushNamed(Routes.restoreWalletFromHardwareWallet, arguments: {
+ "showUnavailable": false,
+ "availableHardwareWalletTypes": [
+ HardwareWalletType.cupcake,
+ HardwareWalletType.coldcard,
+ HardwareWalletType.seedsigner,
+ ],
+ "onSelect": (BuildContext context, HardwareWalletType hwType) async {
+ await _otherSettingsViewModel.onHardwareWalletTypeChanged(hwType);
+ Navigator.pop(context);
+ },
+ }),
+ ),
+ ListItemRegularRow(
+ keyValue: "security_backup_page_sign_and_verify",
+ label: S.of(context).sign_verify_title,
+ onTap: () {
+ Navigator.of(context).pushNamed(Routes.signPage);
+ }),
+ ],
+ if(FeatureFlag.hasDevOptions)
+ "dev": [
+ if(_otherSettingsViewModel.walletType == WalletType.bitcoin) ...[
+ ListItemRegularRow(
+ keyValue: "export_lightning_logs",
+ label: S.of(context).export_lightning_logs,
+ onTap: () => onExportLNLog(context)
),
- SettingsVersionCell(
- title: S.of(context).version(_otherSettingsViewModel.currentVersion),
+ ListItemRegularRow(
+ keyValue: "export_payjoin_logs",
+ label: S.of(context).export_payjoin_logs,
+ onTap: () => onExportPJLog(context)
),
],
- ),
- ),
- );
-
+ if (FeatureFlag.hasDevOptions &&
+ _otherSettingsViewModel.walletType == WalletType.monero)
+ ListItemRegularRow(
+ keyValue: "[dev] monero background sync",
+ label: "[dev] monero background sync",
+ onTap: () => Navigator.of(context).pushNamed(Routes.devMoneroBackgroundSync)
+ ),
+ if (FeatureFlag.hasDevOptions &&
+ [WalletType.monero, WalletType.wownero, WalletType.zano]
+ .contains(_otherSettingsViewModel.walletType))
+ ListItemRegularRow(
+ keyValue: "[dev] xmr call profiler",
+ label: "[dev] xmr call profiler",
+ onTap: () => Navigator.of(context).pushNamed(Routes.devMoneroCallProfiler)
+ ),
+ if (FeatureFlag.hasDevOptions &&
+ [WalletType.monero].contains(_otherSettingsViewModel.walletType))
+ ListItemRegularRow(
+ keyValue: '[dev] xmr wallet cache debug',
+ label: '[dev] xmr wallet cache debug',
+ onTap: () => Navigator.of(context).pushNamed(Routes.devMoneroWalletCacheDebug)
+ ),
+ ListItemRegularRow(
+ keyValue: '[dev] shared preferences',
+ label: '[dev] shared preferences',
+ onTap: () => Navigator.of(context).pushNamed(Routes.devSharedPreferences)
+ ),
+ ListItemRegularRow(
+ keyValue: '[dev] secure storage preferences',
+ label: '[dev] secure storage preferences',
+ onTap: () => Navigator.of(context).pushNamed(Routes.devSecurePreferences)
+ ),
+ ListItemRegularRow(
+ keyValue: '[dev] background sync logs',
+ label: '[dev] background sync logs',
+ onTap: () => Navigator.of(context).pushNamed(Routes.devBackgroundSyncLogs)
+ ),
+ ListItemRegularRow(
+ keyValue: '[dev] socket health logs',
+ label: '[dev] socket health logs',
+ onTap: () => Navigator.of(context).pushNamed(Routes.devSocketHealthLogs)
+ ),
+ ListItemRegularRow(
+ keyValue: '[dev] network requests logs',
+ label: '[dev] network requests logs',
+ onTap: () => Navigator.of(context).pushNamed(Routes.devNetworkRequests)
+ ),
+ ListItemRegularRow(
+ keyValue: '[dev] exchange provider logs',
+ label: '[dev] exchange provider logs',
+ onTap: () => Navigator.of(context).pushNamed(Routes.devExchangeProviderLogs)
+ ),
+ ListItemRegularRow(
+ keyValue: '[dev] *QR tools',
+ label: '[dev] *QR tools',
+ onTap: () => Navigator.of(context).pushNamed(Routes.devExchangeProviderLogs)
+ ),
+ ListItemRegularRow(
+ keyValue: '[dev] browse sqlite db',
+ label: '[dev] browse sqlite db',
+ onTap: () async {
+ final data = await dumpDb();
+ Navigator.of(context).push(
+ MaterialPageRoute(builder: (context) =>
+ JsonExplorerPage(data: data, title: 'sqlite db')),
+ );
+ }
+ ),
+ ]
+ }
+ ),
+ );
+ }
Future<void> onExportLNLog(BuildContext context) async {
final file = await _otherSettingsViewModel.getLightningLog();
diff --git a/lib/src/screens/settings/privacy_page.dart b/lib/src/screens/settings/privacy_page.dart
index 8eb1f785..c1622313 100644
--- a/lib/src/screens/settings/privacy_page.dart
+++ b/lib/src/screens/settings/privacy_page.dart
@@ -1,15 +1,12 @@
-import 'package:cake_wallet/entities/exchange_api_mode.dart';
-import 'package:cake_wallet/entities/fiat_api_mode.dart';
+import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item_regular_row.dart';
+import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item_toggle.dart';
import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/new-ui/widgets/modal_header.dart';
+import 'package:cake_wallet/new-ui/widgets/modal_page_wrapper.dart';
+import 'package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
-import 'package:cake_wallet/src/screens/settings/widgets/settings_cell_with_arrow.dart';
-import 'package:cake_wallet/src/screens/settings/widgets/settings_choices_cell.dart';
-import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart';
-import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
-import 'package:cake_wallet/utils/device_info.dart';
-import 'package:cake_wallet/utils/show_pop_up.dart';
-import 'package:cake_wallet/view_model/settings/choices_list_item.dart';
+import 'package:cake_wallet/src/widgets/new_list_row/new_list_section.dart';
import 'package:cake_wallet/view_model/settings/privacy_settings_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
@@ -18,195 +15,94 @@ class PrivacyPage extends BasePage {
PrivacyPage(this._privacySettingsViewModel);
@override
- String get title => S.current.privacy_settings;
+ bool get hideAppBar => true;
final PrivacySettingsViewModel _privacySettingsViewModel;
@override
Widget body(BuildContext context) {
- return SingleChildScrollView(
- child: Container(
- padding: EdgeInsets.only(top: 10),
- child: Observer(builder: (_) {
- return Column(
- mainAxisSize: MainAxisSize.min,
- children: [
- SettingsChoicesCell(
- ChoicesListItem<FiatApiMode>(
- title: S.current.fiat_api,
- items: FiatApiMode.all,
- selectedItem: _privacySettingsViewModel.fiatApiMode,
- onItemSelected: (FiatApiMode fiatApiMode) =>
- _privacySettingsViewModel.setFiatMode(fiatApiMode),
- ),
- ),
- SettingsChoicesCell(
- ChoicesListItem<ExchangeApiMode>(
- title: S.current.swap,
- items: ExchangeApiMode.all,
- selectedItem: _privacySettingsViewModel.exchangeStatus,
- onItemSelected: (ExchangeApiMode mode) =>
- _privacySettingsViewModel.setExchangeApiMode(mode),
- ),
- ),
- if (_privacySettingsViewModel.canUseLightning)
- SettingsSwitcherCell(
- title: S.of(context).enable_lightning,
- value: _privacySettingsViewModel.useLightning,
- onValueChange: (_, value) => _privacySettingsViewModel.setUseLightning(value),
- ),
- if (_privacySettingsViewModel.canUsePayjoin)
- SettingsSwitcherCell(
- title: S.of(context).use_payjoin,
- value: _privacySettingsViewModel.usePayjoin,
- onValueChange: (BuildContext _, bool value) {
- _privacySettingsViewModel.setUsePayjoin(value);
- },
- ),
- SettingsSwitcherCell(
- title: S.current.settings_save_recipient_address,
- value: _privacySettingsViewModel.shouldSaveRecipientAddress,
- onValueChange: (BuildContext _, bool value) {
- _privacySettingsViewModel.setShouldSaveRecipientAddress(value);
- }),
- if (_privacySettingsViewModel.isAutoGenerateSubaddressesVisible)
- SettingsSwitcherCell(
- title: _privacySettingsViewModel.isMoneroWallet
- ? S.current.auto_generate_subaddresses
- : S.current.auto_generate_addresses,
- value: _privacySettingsViewModel.isAutoGenerateSubaddressesEnabled,
- onValueChange: (BuildContext _, bool value) {
- _privacySettingsViewModel.setAutoGenerateSubaddresses(value);
- },
- ),
- if (DeviceInfo.instance.isMobile)
- SettingsSwitcherCell(
- title: S.current.prevent_screenshots,
- value: _privacySettingsViewModel.isAppSecure,
- onValueChange: (BuildContext _, bool value) {
- _privacySettingsViewModel.setIsAppSecure(value);
- },
- ),
- SettingsSwitcherCell(
- title: S.current.disable_buy,
- value: _privacySettingsViewModel.disableTradeOption,
- onValueChange: (BuildContext _, bool value) {
- _privacySettingsViewModel.setDisableTradeOption(value);
- },
- ),
- SettingsSwitcherCell(
- title: S.current.disable_automatic_exchange_status_updates,
- value: _privacySettingsViewModel.disableAutomaticExchangeStatusUpdates,
- onValueChange: (BuildContext _, bool value) {
- _privacySettingsViewModel.setDisableAutomaticExchangeStatusUpdates(value);
- },
- ),
- // SettingsSwitcherCell(
- // title: S.current.disable_bulletin,
- // value: _privacySettingsViewModel.disableBulletin,
- // onValueChange: (BuildContext _, bool value) {
- // _privacySettingsViewModel.setDisableBulletin(value);
- // },
- // ),
- if (_privacySettingsViewModel.canUseBlinkProtection)
- SettingsSwitcherCell(
- title: S.current.use_blink_protection,
- value: _privacySettingsViewModel.useBlinkProtection,
- onValueChange: (BuildContext _, bool value) {
- _privacySettingsViewModel.setUseBlinkProtection(value);
- },
- ),
- if (_privacySettingsViewModel.canUseEtherscan)
- SettingsSwitcherCell(
- title: S.current.etherscan_history,
- value: _privacySettingsViewModel.useEtherscan,
- onValueChange: (BuildContext _, bool value) {
- _privacySettingsViewModel.setUseEtherscan(value);
- },
- ),
- if (_privacySettingsViewModel.canUsePolygonScan)
- SettingsSwitcherCell(
- title: S.current.polygonscan_history,
- value: _privacySettingsViewModel.usePolygonScan,
- onValueChange: (BuildContext _, bool value) {
- _privacySettingsViewModel.setUsePolygonScan(value);
- },
- ),
- if (_privacySettingsViewModel.canUseBaseScan)
- SettingsSwitcherCell(
- title: S.current.basescan_history,
- value: _privacySettingsViewModel.useBaseScan,
- onValueChange: (BuildContext _, bool value) {
- _privacySettingsViewModel.setUseBaseScan(value);
- },
- ),
- if (_privacySettingsViewModel.canUseArbiScan)
- SettingsSwitcherCell(
- title: S.current.arbiscan_history,
- value: _privacySettingsViewModel.useArbiScan,
- onValueChange: (BuildContext _, bool value) {
- _privacySettingsViewModel.setUseArbiScan(value);
- },
- ),
- if (_privacySettingsViewModel.canUseBscScan)
- SettingsSwitcherCell(
- title: S.current.bscscan_history,
- value: _privacySettingsViewModel.useBscScan,
- onValueChange: (BuildContext _, bool value) {
- _privacySettingsViewModel.setUseBscScan(value);
- },
- ),
- if (_privacySettingsViewModel.canUseTronGrid)
- SettingsSwitcherCell(
- title: S.current.trongrid_history,
- value: _privacySettingsViewModel.useTronGrid,
- onValueChange: (BuildContext _, bool value) {
- _privacySettingsViewModel.setUseTronGrid(value);
- },
- ),
- if (_privacySettingsViewModel.canUseMempoolFeeAPI)
- SettingsSwitcherCell(
- title: S.current.enable_mempool_api,
- value: _privacySettingsViewModel.useMempoolFeeAPI,
- onValueChange: (BuildContext _, bool isEnabled) async {
- if (!isEnabled) {
- final bool confirmation = await showPopUp<bool>(
- context: context,
- builder: (BuildContext context) {
- return AlertWithTwoActions(
- alertTitle: S.of(context).warning,
- alertContent: S.of(context).disable_fee_api_warning,
- rightButtonText: S.of(context).confirm,
- leftButtonText: S.of(context).cancel,
- actionRightButton: () => Navigator.of(context).pop(true),
- actionLeftButton: () => Navigator.of(context).pop(false));
- }) ??
- false;
- if (confirmation) {
- _privacySettingsViewModel.setUseMempoolFeeAPI(isEnabled);
- }
- return;
- }
-
- _privacySettingsViewModel.setUseMempoolFeeAPI(isEnabled);
- },
- ),
- SettingsCellWithArrow(
- title: S.current.domain_looks_up,
- handler: (context) => Navigator.of(context).pushNamed(Routes.domainLookupsPage),
- ),
- if(_privacySettingsViewModel.hasCoinControl)
- SettingsCellWithArrow(
- title: "Coin Control",
- handler: (context) => Navigator.of(context).pushNamed(Routes.unspentCoinsList),
+ return ModalPageWrapper(
+ topBar: ModalTopBar(
+ title: "",
+ leadingIcon: Icon(Icons.arrow_back_ios_new),
+ onLeadingPressed: () => Navigator.of(context).pop(),
+ ),
+ header: ModalHeader(
+ iconPath: "assets/new-ui/settings_row_icons/privacy.svg",
+ message: S.of(context).privacy_desc,
+ title: S.of(context).privacy),
+ content: SingleChildScrollView(
+ child: Container(
+ child: Observer(builder: (_) {
+ return Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ NewListSections(
+ sections: {
+ "1": [
+ if (_privacySettingsViewModel.isAutoGenerateSubaddressesVisible)
+ ListItemToggle(
+ keyValue: "auto_generate_subaddresses",
+ label: _privacySettingsViewModel.isMoneroWallet
+ ? S.of(context).auto_generate_subaddresses
+ : S.of(context).auto_generate_addresses,
+ value: _privacySettingsViewModel.isAutoGenerateSubaddressesEnabled,
+ onChanged: (val) {
+ _privacySettingsViewModel.setAutoGenerateSubaddresses(val);
+ }),
+ ListItemToggle(
+ keyValue: "save_recipient_address",
+ label: S.of(context).settings_save_recipient_address,
+ value: _privacySettingsViewModel.shouldSaveRecipientAddress,
+ onChanged: (val) {
+ _privacySettingsViewModel.setShouldSaveRecipientAddress(val);
+ }),
+ if (_privacySettingsViewModel.canUsePayjoin)
+ ListItemToggle(
+ keyValue: "use_payjoin",
+ label: S.of(context).use_payjoin,
+ value: _privacySettingsViewModel.usePayjoin,
+ onChanged: (val) {
+ _privacySettingsViewModel.setUsePayjoin(val);
+ }),
+ if (_privacySettingsViewModel.canUseLightning)
+ ListItemToggle(
+ keyValue: "enable_lightning",
+ label: S.of(context).enable_lightning,
+ value: _privacySettingsViewModel.useLightning,
+ onChanged: (val) {
+ _privacySettingsViewModel.setUseLightning(val);
+ }),
+ ],
+ "": [
+ if (_privacySettingsViewModel.isBitcoin)
+ ListItemRegularRow(
+ iconPath: "assets/new-ui/settings_row_icons/silent-payments.svg",
+ keyValue: "silent_payments",
+ label: S.of(context).silent_payments,
+ onTap: () =>
+ Navigator.of(context).pushNamed(Routes.silentPaymentsSettings)),
+ if (_privacySettingsViewModel.isLitecoin)
+ ListItemRegularRow(
+ iconPath: "assets/new-ui/settings_row_icons/mweb.svg",
+ keyValue: "mweb",
+ label: "MWEB",
+ onTap: () =>
+ Navigator.of(context).pushNamed(Routes.mwebSettings)),
+ if (_privacySettingsViewModel.hasCoinControl)
+ ListItemRegularRow(
+ iconPath: "assets/new-ui/settings_row_icons/coin-control.svg",
+ keyValue: "coin_control",
+ label: "Coin Control",
+ onTap: () =>
+ Navigator.of(context).pushNamed(Routes.unspentCoinsList)),
+ ],
+ }
),
- // SettingsCellWithArrow(
- // title: 'Trocador providers',
- // handler: (context) => Navigator.of(context).pushNamed(Routes.trocadorProvidersPage),
- // ),
- ],
- );
- }),
+ ],
+ );
+ }),
+ ),
),
);
}
diff --git a/lib/src/screens/settings/security_backup_page.dart b/lib/src/screens/settings/security_backup_page.dart
index 714b6953..37fb7c71 100644
--- a/lib/src/screens/settings/security_backup_page.dart
+++ b/lib/src/screens/settings/security_backup_page.dart
@@ -2,9 +2,12 @@ import 'dart:io';
import 'package:cake_wallet/core/auth_service.dart';
import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item_regular_row.dart';
+import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item_selector.dart';
import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item_toggle.dart';
import 'package:cake_wallet/entities/pin_code_required_duration.dart';
import 'package:cake_wallet/new-ui/widgets/modal_header.dart';
+import 'package:cake_wallet/new-ui/widgets/modal_page_wrapper.dart';
+import 'package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/generated/i18n.dart';
@@ -14,7 +17,6 @@ import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
import 'package:cake_wallet/src/widgets/new_list_row/new_list_section.dart';
import 'package:cake_wallet/src/widgets/picker.dart';
import 'package:cake_wallet/utils/device_info.dart';
-import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/utils/feature_flag.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/settings/security_settings_view_model.dart';
@@ -28,7 +30,10 @@ class SecurityBackupPage extends BasePage {
final AuthService _authService;
@override
- String get title => S.current.security;
+ bool get hideAppBar => true;
+
+ @override
+ String get title => S.current.security_and_backup;
final SecuritySettingsViewModel _securitySettingsViewModel;
@@ -36,170 +41,160 @@ class SecurityBackupPage extends BasePage {
@override
Widget body(BuildContext context) {
- return Container(
- padding: EdgeInsets.only(top: 10),
- child: Padding(
- padding: const EdgeInsets.symmetric(horizontal: 18.0),
- child: Column(
- spacing: 16,
- mainAxisSize: MainAxisSize.min,
- children: [
- ModalHeader(
- iconPath: "assets/new-ui/settings_row_icons/security.svg",
- message: S.of(context).privacy_and_security_desc,
- title: S.of(context).security),
- Observer(
- builder: (_) => NewListSections(sections: {
- "": [
- if (DeviceInfo.instance.isMobile || Platform.isMacOS || Platform.isLinux)
- ListItemToggle(
- keyValue: "security_backup_page_allow_biometrics_button_key",
- label: S.current.settings_allow_biometrical_authentication,
- value: _securitySettingsViewModel.allowBiometricalAuthentication,
- onChanged: (bool value) {
- if (value) {
- _authService.authenticateAction(
- context,
- onAuthSuccess: (isAuthenticatedSuccessfully) async {
- if (isAuthenticatedSuccessfully) {
- if (await _securitySettingsViewModel.biometricAuthenticated()) {
- _securitySettingsViewModel.setAllowBiometricalAuthentication(
- isAuthenticatedSuccessfully);
- }
- } else {
+ return ModalPageWrapper(
+ topBar: ModalTopBar(
+ title: "",
+ leadingIcon: Icon(Icons.arrow_back_ios_new),
+ onLeadingPressed: () => Navigator.of(context).pop()),
+ header: ModalHeader(
+ iconPath: "assets/new-ui/settings_row_icons/security.svg",
+ message: S.of(context).privacy_and_security_desc,
+ title: S.of(context).security),
+ content: Column(
+ spacing: 16,
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Observer(
+ builder: (_) => NewListSections(sections: {
+ "": [
+ if (DeviceInfo.instance.isMobile || Platform.isMacOS || Platform.isLinux)
+ ListItemToggle(
+ keyValue: "security_backup_page_allow_biometrics_button_key",
+ label: S.current.settings_allow_biometrical_authentication,
+ value: _securitySettingsViewModel.allowBiometricalAuthentication,
+ onChanged: (bool value) {
+ if (value) {
+ _authService.authenticateAction(
+ context,
+ onAuthSuccess: (isAuthenticatedSuccessfully) async {
+ if (isAuthenticatedSuccessfully) {
+ if (await _securitySettingsViewModel.biometricAuthenticated()) {
_securitySettingsViewModel.setAllowBiometricalAuthentication(
isAuthenticatedSuccessfully);
}
- },
- conditionToDetermineIfToUse2FA: _securitySettingsViewModel
- .shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
- );
- } else {
- _securitySettingsViewModel.setAllowBiometricalAuthentication(value);
- }
- }),
- if (FeatureFlag.duressPinEnabled)
- ListItemToggle(
- keyValue: "security_backup_page_duress_pin_button_key",
- label: "Duress PIN",
- value: _securitySettingsViewModel.enableDuressPin,
- onChanged: (bool value) {
- _authService
- .authenticateAction(context, route: Routes.securityBackupDuressPin,
- onAuthSuccess: (isAuthenticatedSuccessfully) async {
- if (isAuthenticatedSuccessfully) {
- if (!value) {
- _securitySettingsViewModel.setEnableDuressPin(value);
- _securitySettingsViewModel.clearDuressPin();
- return;
+ } else {
+ _securitySettingsViewModel.setAllowBiometricalAuthentication(
+ isAuthenticatedSuccessfully);
}
- final res = await _showDuressPinDescription(context);
- if (res) {
- final confirmation = await _showDuressPinConfirmation(context);
+ },
+ conditionToDetermineIfToUse2FA: _securitySettingsViewModel
+ .shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
+ );
+ } else {
+ _securitySettingsViewModel.setAllowBiometricalAuthentication(value);
+ }
+ }),
+ if (DeviceInfo.instance.isMobile)
+ ListItemToggle(
+ keyValue: "display_settings_prevent_screen_capture",
+ label: S.of(context).prevent_screenshots,
+ value: _securitySettingsViewModel.isAppSecure,
+ onChanged: (val) {
+ _securitySettingsViewModel.setIsAppSecure(val);
+ }),
+ if (FeatureFlag.duressPinEnabled)
+ ListItemToggle(
+ keyValue: "security_backup_page_duress_pin_button_key",
+ label: "Duress PIN",
+ value: _securitySettingsViewModel.enableDuressPin,
+ onChanged: (bool value) {
+ _authService
+ .authenticateAction(context, route: Routes.securityBackupDuressPin,
+ onAuthSuccess: (isAuthenticatedSuccessfully) async {
+ if (isAuthenticatedSuccessfully) {
+ if (!value) {
+ _securitySettingsViewModel.setEnableDuressPin(value);
+ _securitySettingsViewModel.clearDuressPin();
+ return;
+ }
+ final res = await _showDuressPinDescription(context);
+ if (res) {
+ final confirmation = await _showDuressPinConfirmation(context);
- if (confirmation) {
- Navigator.of(context).pushNamed(
- Routes.setupDuressPin,
- arguments:
- (PinCodeState<PinCodeWidget> pinCtx, String _) async {
- pinCtx.close();
- _securitySettingsViewModel.setEnableDuressPin(true);
- },
- );
- }
+ if (confirmation) {
+ Navigator.of(context).pushNamed(
+ Routes.setupDuressPin,
+ arguments:
+ (PinCodeState<PinCodeWidget> pinCtx, String _) async {
+ pinCtx.close();
+ _securitySettingsViewModel.setEnableDuressPin(true);
+ },
+ );
}
}
- },
- conditionToDetermineIfToUse2FA: _securitySettingsViewModel
- .shouldRequireTOTP2FAForAllSecurityAndBackupSettings);
- }),
- ListItemRegularRow(
- keyValue: "security_backup_page_require_pin_after_button_key",
- label: S.current.require_pin_after,
- trailingText: _securitySettingsViewModel.pinCodeRequiredDuration.toString(),
- onTap: () async {
- final items = PinCodeRequiredDuration.values;
+ }
+ },
+ conditionToDetermineIfToUse2FA: _securitySettingsViewModel
+ .shouldRequireTOTP2FAForAllSecurityAndBackupSettings);
+ }),
+ ListItemSelector(
+ keyValue: "security_backup_page_require_pin_after_button_key",
+ label: S.current.require_pin_after,
+ options: [_securitySettingsViewModel.pinCodeRequiredDuration.toString()],
+ onTap: () async {
+ final items = PinCodeRequiredDuration.values;
- final selectedAtIndex =
- items.indexOf(_securitySettingsViewModel.pinCodeRequiredDuration);
+ final selectedAtIndex =
+ items.indexOf(_securitySettingsViewModel.pinCodeRequiredDuration);
- await showPopUp<void>(
- context: context,
- builder: (_) => Picker(
- items: items,
- selectedAtIndex: selectedAtIndex,
- mainAxisAlignment: MainAxisAlignment.start,
- onItemSelected: (PinCodeRequiredDuration item) {
- _securitySettingsViewModel.setPinCodeRequiredDuration(item);
- },
- isSeparated: false,
- ),
- );
- }),
- // if (!_isHardwareWallet)
- // ListItemRegularRow(
- // keyValue: "security_backup_page_show_keys_button_key",
- // label: S.current.show_keys,
- // onTap: () {
- // _authService.authenticateAction(
- // context,
- // route: Routes.showKeys,
- // conditionToDetermineIfToUse2FA: _securitySettingsViewModel
- // .shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
- // );
- // }),
- // if (!SettingsStoreBase.walletPasswordDirectInput)
- // ListItemRegularRow(
- // keyValue: "security_backup_page_change_password_button_key",
- // label: S.current.create_backup,
- // onTap: () {
- // _authService.authenticateAction(
- // context,
- // route: Routes.backup,
- // conditionToDetermineIfToUse2FA: _securitySettingsViewModel
- // .shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
- // );
- // }),
- ListItemRegularRow(
- keyValue: "security_backup_page_change_pin_button_key",
- label: S.current.settings_change_pin,
- onTap: () {
- _authService.authenticateAction(
- context,
- route: Routes.setupPin,
- arguments: (PinCodeState<PinCodeWidget> setupPinContext, String _) {
- setupPinContext.close();
+ await showPopUp<void>(
+ context: context,
+ builder: (_) => Picker(
+ items: items,
+ selectedAtIndex: selectedAtIndex,
+ mainAxisAlignment: MainAxisAlignment.start,
+ onItemSelected: (PinCodeRequiredDuration item) {
+ _securitySettingsViewModel.setPinCodeRequiredDuration(item);
},
- conditionToDetermineIfToUse2FA: _securitySettingsViewModel
- .shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
- );
- }),
- ListItemRegularRow(
- keyValue: "security_backup_page_sign_and_verify",
- label: S.current.sign_verify_title,
- onTap: () {
- Navigator.of(context).pushNamed(Routes.signPage);
- }),
- ListItemRegularRow(
- keyValue: "security_backup_page_totp_2fa_button_key",
- label: _securitySettingsViewModel.useTotp2FA
- ? S.current.modify_2fa
- : S.current.setup_2fa,
- onTap: () {
- _authService.authenticateAction(
- context,
- route: _securitySettingsViewModel.useTotp2FA
- ? Routes.modify2FAPage
- : Routes.setup2faInfoPage,
- conditionToDetermineIfToUse2FA: _securitySettingsViewModel
- .shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
- );
- })
- ]
- }),
- ),
- ],
- ),
+ isSeparated: false,
+ ),
+ );
+ }),
+ // if (!_isHardwareWallet)
+ // ListItemRegularRow(
+ // keyValue: "security_backup_page_show_keys_button_key",
+ // label: S.current.show_keys,
+ // onTap: () {
+ // _authService.authenticateAction(
+ // context,
+ // route: Routes.showKeys,
+ // conditionToDetermineIfToUse2FA: _securitySettingsViewModel
+ // .shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
+ // );
+ // }),
+ ListItemRegularRow(
+ keyValue: "security_backup_page_change_pin_button_key",
+ label: S.current.settings_change_pin,
+ onTap: () {
+ _authService.authenticateAction(
+ context,
+ route: Routes.setupPin,
+ arguments: (PinCodeState<PinCodeWidget> setupPinContext, String _) {
+ setupPinContext.close();
+ },
+ conditionToDetermineIfToUse2FA: _securitySettingsViewModel
+ .shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
+ );
+ }),
+ ListItemRegularRow(
+ keyValue: "security_backup_page_totp_2fa_button_key",
+ label: _securitySettingsViewModel.useTotp2FA
+ ? S.current.modify_2fa
+ : S.current.setup_2fa,
+ onTap: () {
+ _authService.authenticateAction(
+ context,
+ route: _securitySettingsViewModel.useTotp2FA
+ ? Routes.modify2FAPage
+ : Routes.setup2faInfoPage,
+ conditionToDetermineIfToUse2FA: _securitySettingsViewModel
+ .shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
+ );
+ })
+ ]
+ }),
+ ),
+ ],
),
);
}
diff --git a/lib/src/screens/settings/widgets/settings_choices_cell.dart b/lib/src/screens/settings/widgets/settings_choices_cell.dart
index 798093f8..fdf81d56 100644
--- a/lib/src/screens/settings/widgets/settings_choices_cell.dart
+++ b/lib/src/screens/settings/widgets/settings_choices_cell.dart
@@ -12,9 +12,13 @@ class SettingsChoicesCell extends StatelessWidget {
@override
Widget build(BuildContext context) {
+ final items = choicesListItem.items;
+ final selectedIndex = items.indexOf(choicesListItem.selectedItem);
+ final itemCount = items.length;
+
return Container(
color: useGenericColor ? Theme.of(context).colorScheme.surface : null,
- padding: padding ?? EdgeInsets.only(left: 24, right: 24, top: 16, bottom: 16),
+ padding: padding ?? const EdgeInsets.only(left: 24, right: 24, top: 16, bottom: 16),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
@@ -33,46 +37,68 @@ class SettingsChoicesCell extends StatelessWidget {
Center(
child: Container(
decoration: BoxDecoration(
- borderRadius: BorderRadius.circular(10),
+ borderRadius: BorderRadius.circular(12),
border: useGenericColor
? null
: Border.all(
color: Theme.of(context).colorScheme.surfaceContainerHighest,
width: 1.5,
),
- color:
- useGenericColor ? Theme.of(context).colorScheme.surfaceContainerHighest : null,
+ color: useGenericColor
+ ? Theme.of(context).colorScheme.surfaceContainerHighest
+ : null,
),
- child: Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: choicesListItem.items.map((dynamic e) {
- final isSelected = choicesListItem.selectedItem == e;
- return Expanded(
- child: GestureDetector(
- onTap: () {
- choicesListItem.onItemSelected.call(e);
- },
- child: Container(
- padding: EdgeInsets.symmetric(vertical: 8),
- decoration: BoxDecoration(
- borderRadius: BorderRadius.circular(10),
- color: isSelected ? Theme.of(context).colorScheme.primary : null,
- ),
- child: Center(
- child: Text(
- choicesListItem.displayItem.call(e),
- style: Theme.of(context).textTheme.bodyMedium?.copyWith(
- color: isSelected
- ? Theme.of(context).colorScheme.onPrimary
- : Theme.of(context).colorScheme.onSurfaceVariant,
- fontWeight: isSelected ? FontWeight.w600 : FontWeight.normal,
- ),
+ child: LayoutBuilder(
+ builder: (context, constraints) {
+ final itemWidth = constraints.maxWidth / itemCount;
+ return Stack(
+ children: [
+ if (selectedIndex >= 0)
+ AnimatedPositioned(
+ duration: const Duration(milliseconds: 450),
+ curve: Curves.easeInOut,
+ left: selectedIndex * itemWidth,
+ top: 0,
+ bottom: 0,
+ width: itemWidth,
+ child: Container(
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(12),
+ color: Theme.of(context).colorScheme.primary,
+ ),
),
),
+ Row(
+ children: items.map((dynamic e) {
+ final isSelected = choicesListItem.selectedItem == e;
+ return Expanded(
+ child: GestureDetector(
+ onTap: () => choicesListItem.onItemSelected.call(e),
+ child: Container(
+ padding: const EdgeInsets.symmetric(vertical: 8),
+ color: Colors.transparent,
+ child: Center(
+ child: AnimatedDefaultTextStyle(
+ duration: const Duration(milliseconds: 220),
+ curve: Curves.easeInOut,
+ style: Theme.of(context).textTheme.bodyMedium!.copyWith(
+ color: isSelected
+ ? Theme.of(context).colorScheme.onPrimary
+ : Theme.of(context).colorScheme.onSurfaceVariant,
+ fontWeight:
+ isSelected ? FontWeight.w600 : FontWeight.normal,
+ ),
+ child: Text(choicesListItem.displayItem.call(e)),
+ ),
+ ),
+ ),
+ ),
+ );
+ }).toList(),
),
- ),
+ ],
);
- }).toList(),
+ },
),
),
),
@@ -80,4 +106,4 @@ class SettingsChoicesCell extends StatelessWidget {
),
);
}
-}
+}
\ No newline at end of file
diff --git a/lib/src/screens/settings/widgets/settings_switcher_cell.dart b/lib/src/screens/settings/widgets/settings_switcher_cell.dart
index 34019c2c..1c18036a 100644
--- a/lib/src/screens/settings/widgets/settings_switcher_cell.dart
+++ b/lib/src/screens/settings/widgets/settings_switcher_cell.dart
@@ -13,6 +13,7 @@ class SettingsSwitcherCell extends StandardListRow {
Key? key,
this.padding,
this.switchBackgroundColor,
+ this.height = 56,
}) : super(title: title, isSelected: false, decoration: decoration, onTap: onTap, key: key);
final bool value;
@@ -20,6 +21,7 @@ class SettingsSwitcherCell extends StandardListRow {
final void Function(BuildContext context, bool value)? onValueChange;
final Widget? leading;
final EdgeInsets? padding;
+ final double? height;
@override
Widget buildTrailing(BuildContext context) => StandardSwitch(
@@ -33,7 +35,7 @@ class SettingsSwitcherCell extends StandardListRow {
final leading = buildLeading(context);
final trailing = buildTrailing(context);
return Container(
- height: 56,
+ height: height,
padding: padding ?? EdgeInsets.only(left: 12, right: 12),
child: TextButton(
onPressed: () {
diff --git a/lib/src/screens/settings/widgets/settings_theme_choice.dart b/lib/src/screens/settings/widgets/settings_theme_choice.dart
index ed6d8ca6..c96743eb 100644
--- a/lib/src/screens/settings/widgets/settings_theme_choice.dart
+++ b/lib/src/screens/settings/widgets/settings_theme_choice.dart
@@ -12,9 +12,9 @@ class SettingsThemeChoicesCell extends StatelessWidget {
final DisplaySettingsViewModel _displaySettingsViewModel;
- final double cellHeight = 25;
+ final double cellHeight = 12;
final double cellWidth = 12;
- final double cellRadius = 8;
+ final double cellRadius = 18;
@override
Widget build(BuildContext context) {
@@ -28,14 +28,17 @@ class SettingsThemeChoicesCell extends StatelessWidget {
final previewHeight = _getResponsivePreviewHeight(screenHeight);
final previewWidth = previewHeight * 0.6;
- return Container(
+ return AnimatedContainer(
+ duration: const Duration(milliseconds: 350),
+ curve: Curves.easeInOut,
height: getHeight(context, currentTheme, currentTheme.hasAccentColors),
- padding: EdgeInsets.all(12),
+ padding: EdgeInsets.all(14),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
- Expanded(
+ SizedBox(
+ height: previewHeight,
child: ListView.builder(
itemCount: availableThemes.length,
scrollDirection: Axis.horizontal,
@@ -50,16 +53,16 @@ class SettingsThemeChoicesCell extends StatelessWidget {
onTap: () {
_displaySettingsViewModel.onThemeSelected(theme);
},
- child: Container(
+ child: AnimatedContainer(
+ duration: const Duration(milliseconds: 350),
+ curve: Curves.easeInOut,
margin: EdgeInsets.only(right: 24),
- decoration: BoxDecoration(
- borderRadius: BorderRadius.circular(cellRadius),
- border: isSelected
- ? Border.all(
- color: Theme.of(context).colorScheme.primary,
+ decoration: ShapeDecoration(
+ shape: RoundedSuperellipseBorder(borderRadius: BorderRadius.circular(cellRadius),
+ side: BorderSide(
+ color: isSelected ? Theme.of(context).colorScheme.primary : Colors.transparent,
strokeAlign: BorderSide.strokeAlignOutside)
- : null,
- ),
+ )),
child: ClipRRect(
borderRadius: BorderRadius.circular(cellRadius),
child: CakeImageWidget(
@@ -75,56 +78,94 @@ class SettingsThemeChoicesCell extends StatelessWidget {
},
),
),
- if (_displaySettingsViewModel.currentTheme.hasAccentColors) ...[
- SizedBox(height: cellHeight),
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Text(
- S.of(context).accent_color,
- style: Theme.of(context).textTheme.bodyMedium,
- ),
- Container(
- child: Row(
- children: availableAccentColors.map((accentColor) {
- final isSelected = _displaySettingsViewModel
- .isAccentColorSelected(accentColor.name.toLowerCase());
- return GestureDetector(
- onTap: () {
- _displaySettingsViewModel
- .onAccentColorSelected(accentColor.name.toLowerCase());
- },
- child: Container(
- width: 26,
- height: 26,
- margin: EdgeInsets.only(right: 11),
- decoration: BoxDecoration(
- borderRadius: BorderRadius.circular(16),
- border: isSelected
- ? Border.all(
- color: Theme.of(context).colorScheme.onSurfaceVariant,
- width: 3)
- : null,
- color: accentColor.color,
- ),
- ),
- );
- }).toList(),
- ),
- ),
- ],
+ AnimatedSwitcher(
+ duration: const Duration(milliseconds: 350),
+ switchInCurve: Curves.easeOut,
+ switchOutCurve: Curves.easeIn,
+ transitionBuilder: (child, animation) => FadeTransition(
+ opacity: animation,
+ child: SizeTransition(
+ sizeFactor: animation,
+ axisAlignment: -1,
+ child: child,
+ ),
),
- ],
+ child: _displaySettingsViewModel.currentTheme.hasAccentColors
+ ? Column(
+ key: const ValueKey('accent'),
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Padding(
+ padding: EdgeInsets.only(top: 14),
+ child: Container(height: 1, color: Theme.of(context).colorScheme.outlineVariant)
+ ),
+ SizedBox(height: cellHeight),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(
+ S.of(context).accent_color,
+ style: Theme.of(context).textTheme.bodyMedium,
+ ),
+ Row(
+ spacing: 4,
+ children: availableAccentColors.map((accentColor) {
+ final isSelected = _displaySettingsViewModel
+ .isAccentColorSelected(accentColor.name.toLowerCase());
+ return GestureDetector(
+ onTap: () {
+ _displaySettingsViewModel
+ .onAccentColorSelected(accentColor.name.toLowerCase());
+ },
+ child: Stack(
+ children: [
+ AnimatedOpacity(
+ duration: Duration(milliseconds: 350),
+ opacity: isSelected ? 1 : 0,
+ child: Container(
+ width:28,height:28,decoration: BoxDecoration(borderRadius: BorderRadius.circular(99999999),border: Border.all(color:Theme.of(context)
+ .colorScheme
+ .onSurface))
+ ),
+ ),
+ AnimatedScale(
+ duration: Duration(milliseconds: 350),
+ scale: isSelected ? 0.8 : 1,
+ child: Container(
+ width: 28,
+ height: 28,
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(99999999),
+ color: accentColor.color),
+ ),
+ ),
+ ],
+ ),
+ );
+ }).toList(),
+ ),
+ ],
+ ),
+ ],
+ )
+ : const SizedBox.shrink(key: ValueKey('no-accent')),
+ ),
if (_displaySettingsViewModel.currentTheme is BlackTheme)
- SettingsSwitcherCell(
- title: S.current.oled_mode,
- value: _displaySettingsViewModel.isBlackThemeOledEnabled,
- onValueChange: (_, bool value) {
- _displaySettingsViewModel.setBlackThemeOled(value);
- },
- padding: EdgeInsets.zero,
- switchBackgroundColor: currentTheme.colorScheme.secondaryContainer,
+ Padding(
+ padding: EdgeInsets.only(top: 12, bottom: 4),
+ child: Container(height: 1, color: Theme.of(context).colorScheme.outlineVariant)
),
+ if (_displaySettingsViewModel.currentTheme is BlackTheme)
+ SettingsSwitcherCell(
+ height: 40,
+ title: S.current.oled_mode,
+ value: _displaySettingsViewModel.isBlackThemeOledEnabled,
+ onValueChange: (_, bool value) {
+ _displaySettingsViewModel.setBlackThemeOled(value);
+ },
+ padding: EdgeInsets.zero,
+ switchBackgroundColor: currentTheme.colorScheme.secondaryContainer,
+ ),
],
),
);
@@ -135,14 +176,14 @@ class SettingsThemeChoicesCell extends StatelessWidget {
double getHeight(BuildContext context, MaterialThemeBase theme, bool hasAccentColors) {
final screenHeight = MediaQuery.of(context).size.height;
- double baseHeight = (screenHeight * 0.25).clamp(150.0, screenHeight * 0.5);
+ double baseHeight = (screenHeight * 0.253).clamp(150.0, screenHeight * 0.5);
if (hasAccentColors) {
- baseHeight += (screenHeight * 0.05).clamp(35.0, 60.0);
+ baseHeight += (screenHeight * 0.60).clamp(35.0, 60.0);
}
if (theme is BlackTheme) {
- baseHeight += (screenHeight * 0.08).clamp(48.0, 96.0);
+ baseHeight += (screenHeight * 0.059).clamp(48.0, 96.0);
}
return baseHeight;
diff --git a/lib/src/widgets/new_list_row/list_Item_style_wrapper.dart b/lib/src/widgets/new_list_row/list_Item_style_wrapper.dart
index a5613756..1e4d5e70 100644
--- a/lib/src/widgets/new_list_row/list_Item_style_wrapper.dart
+++ b/lib/src/widgets/new_list_row/list_Item_style_wrapper.dart
@@ -6,20 +6,21 @@ class ListItemStyleWrapper extends StatelessWidget {
required this.isFirstInSection,
required this.isLastInSection,
required this.builder,
- this.hasImage,
this.onTap,
this.height = 50,
+ this.iconPath,
});
+ final String? iconPath;
final bool isFirstInSection;
final bool isLastInSection;
- final bool ?hasImage;
final double height;
final VoidCallback? onTap;
final Widget Function(BuildContext context, TextStyle textStyle, TextStyle labelStyle) builder;
@override
Widget build(BuildContext context) {
+
final theme = Theme.of(context);
final textStyle = TextStyle(
@@ -60,17 +61,17 @@ class ListItemStyleWrapper extends StatelessWidget {
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12),
child: builder(context, textStyle, labelStyle))))),
- if(hasImage == true && isLastInSection == false) Container(
+ if(iconPath != null && isLastInSection == false) Container(
color: theme.colorScheme.surfaceContainer,
child: Padding(
- padding: const EdgeInsets.only(left: 48, right: 13),
+ padding: const EdgeInsets.only(left: 50, right: 13),
child: Container(height: 1, color: theme.colorScheme.outlineVariant),
),
)
else if(!isLastInSection) Container(
color: theme.colorScheme.surfaceContainer,
child: Padding(
- padding: const EdgeInsets.symmetric(horizontal: 13),
+ padding: const EdgeInsets.symmetric(horizontal: 12),
child: Container(height: 1, color: theme.colorScheme.outlineVariant),
),
)
diff --git a/lib/src/widgets/new_list_row/list_item_checkbox_widget.dart b/lib/src/widgets/new_list_row/list_item_checkbox_widget.dart
index 0d242218..82332872 100644
--- a/lib/src/widgets/new_list_row/list_item_checkbox_widget.dart
+++ b/lib/src/widgets/new_list_row/list_item_checkbox_widget.dart
@@ -37,6 +37,7 @@ class _ListItemCheckboxWidgetState extends State<ListItemCheckboxWidget> {
@override
Widget build(BuildContext context) {
return ListItemStyleWrapper(
+ iconPath: widget.iconPath,
onTap: widget.onTap ?? () {
widget.onChanged(!widget.value);
},
@@ -53,11 +54,11 @@ class _ListItemCheckboxWidgetState extends State<ListItemCheckboxWidget> {
children: [
if (widget.iconPath != null)
widget.iconPath!.toLowerCase().endsWith("svg")
- ? CakeImageWidget(imageUrl:widget.iconPath!, height: 24, width: 24)
+ ? CakeImageWidget(imageUrl:widget.iconPath!, height: 26, width: 26)
: Image.asset(
widget.iconPath!,
- width: 24,
- height: 24,
+ width: 26,
+ height: 26,
),
Expanded(
child: Column(
diff --git a/lib/src/widgets/new_list_row/list_item_regular_row_widget.dart b/lib/src/widgets/new_list_row/list_item_regular_row_widget.dart
index 36e50922..7705cdca 100644
--- a/lib/src/widgets/new_list_row/list_item_regular_row_widget.dart
+++ b/lib/src/widgets/new_list_row/list_item_regular_row_widget.dart
@@ -12,7 +12,6 @@ class ListItemRegularRowWidget extends StatelessWidget {
this.trailingText,
this.iconPath,
this.onTap,
- this.hasImage,
this.isFirstInSection = false,
this.isLastInSection = false,
this.showArrow = true,
@@ -28,7 +27,6 @@ class ListItemRegularRowWidget extends StatelessWidget {
final String? trailingText;
final String? iconPath;
final VoidCallback? onTap;
- final bool? hasImage;
final bool isFirstInSection;
final bool isLastInSection;
final bool showArrow;
@@ -46,7 +44,7 @@ class ListItemRegularRowWidget extends StatelessWidget {
return ListItemStyleWrapper(
onTap: onTap,
- hasImage: iconPath != null ? true : false,
+ iconPath: iconPath,
isFirstInSection: isFirstInSection,
isLastInSection: isLastInSection,
height: subtitle != null ? 64 : 50,
diff --git a/lib/src/widgets/new_list_row/list_item_selector_widget.dart b/lib/src/widgets/new_list_row/list_item_selector_widget.dart
index b3e0790c..cb138906 100644
--- a/lib/src/widgets/new_list_row/list_item_selector_widget.dart
+++ b/lib/src/widgets/new_list_row/list_item_selector_widget.dart
@@ -33,25 +33,25 @@ class ListItemSelectorWidget extends StatelessWidget {
isLastInSection: isLastInSection,
builder: (context, textStyle, labelStyle) {
return Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Flexible(child: Text(label, style: textStyle)),
- Row(
- children: [
- Text(
- options[selectedIndex],
- style: labelStyle,
- ),
- CakeImageWidget(imageUrl:
- "assets/new-ui/chooser.svg",
- colorFilter:
- ColorFilter.mode(theme.colorScheme.onSurfaceVariant, BlendMode.srcIn),
- ),
- SizedBox(width: 8)
- ],
- ),
- ],
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Flexible(child: Text(label, style: textStyle)),
+ Row(
+ spacing: 8,
+ children: [
+ Text(
+ options[selectedIndex],
+ style: labelStyle,
+ ),
+ CakeImageWidget(imageUrl:
+ "assets/new-ui/chooser.svg",
+ colorFilter:
+ ColorFilter.mode(theme.colorScheme.onSurfaceVariant, BlendMode.srcIn),
+ ),
+ ],
+ ),
+ ],
);
});
}
-}
+}
\ No newline at end of file
diff --git a/lib/src/widgets/standard_list.dart b/lib/src/widgets/standard_list.dart
index 3e5fd1bd..f0afdcde 100644
--- a/lib/src/widgets/standard_list.dart
+++ b/lib/src/widgets/standard_list.dart
@@ -6,12 +6,14 @@ class StandardListRow extends StatelessWidget {
StandardListRow({
required this.title,
required this.isSelected,
+ this.subtitle,
this.onTap,
this.decoration,
super.key,
});
final String title;
+ final String? subtitle;
final bool isSelected;
final void Function(BuildContext context)? onTap;
final Decoration? decoration;
@@ -48,18 +50,52 @@ class StandardListRow extends StatelessWidget {
Widget? buildLeading(BuildContext context) => null;
Widget buildCenter(BuildContext context, {required bool hasLeftOffset}) {
+
return Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
if (hasLeftOffset) SizedBox(width: 10),
Expanded(
- child: Text(
- title,
- style: Theme.of(context).textTheme.bodyMedium?.copyWith(
- color: titleColor(context),
- fontWeight: isSelected ? FontWeight.w800 : FontWeight.w400,
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ if (subtitle != null && subtitle!.isNotEmpty)
+ Align(
+ alignment: Alignment.centerLeft,
+ child: Text(
+ textAlign: TextAlign.left,
+ subtitle!,
+ style: Theme.of(context).textTheme.labelMedium?.copyWith(
+ color: titleColor(context),
+ fontWeight: isSelected ? FontWeight.w800 : FontWeight.w400,
+ ),
+ ),
+ ),
+ if (subtitle != null && subtitle!.isNotEmpty)
+ Align(
+ alignment: Alignment.centerLeft,
+ child: Text(
+ textAlign: TextAlign.left,
+ title,
+ style: Theme.of(context).textTheme.labelSmall?.copyWith(
+ color: Theme.of(context).colorScheme.onSurfaceVariant,
+ fontWeight: isSelected ? FontWeight.w800 : FontWeight.w400,
+ ),
+ ),
+ )
+ else
+ Align(
+ alignment: Alignment.centerLeft,
+ child: Text(
+ title,
+ style: Theme.of(context).textTheme.bodyMedium?.copyWith(
+ color: titleColor(context),
+ fontWeight: isSelected ? FontWeight.w800 : FontWeight.w400,
+ ),
),
+ ),
+ ],
),
)
],
@@ -138,6 +174,7 @@ class SectionStandardList extends StatelessWidget {
this.hasTopSeparator = false,
this.scrollController,
this.physics,
+ this.shrinkWrap = false,
}) : totalRows = [];
final int sectionCount;
@@ -150,6 +187,7 @@ class SectionStandardList extends StatelessWidget {
final EdgeInsets dividerPadding;
final ScrollController? scrollController;
final ScrollPhysics? physics;
+ final bool shrinkWrap;
List<Widget> transform(
bool hasTopSeparator,
@@ -208,6 +246,7 @@ class SectionStandardList extends StatelessWidget {
return ListView.separated(
controller: scrollController,
physics: physics,
+ shrinkWrap: shrinkWrap,
separatorBuilder: (_, index) {
final row = totalRows[index];
diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart
index 4fd628bb..b92fb5d2 100644
--- a/lib/view_model/dashboard/dashboard_view_model.dart
+++ b/lib/view_model/dashboard/dashboard_view_model.dart
@@ -671,6 +671,10 @@ abstract class DashboardViewModelBase with Store {
bool get hasLightning =>
wallet.type == WalletType.bitcoin && wallet.isSoftwareWallet && bitcoin!.useLightning(wallet);
+ @computed
+ bool get hasWalletConnect =>
+ isWalletConnectCompatibleChain(wallet.type) && !wallet.isHardwareWallet;
+
@computed
bool get isTestnet => wallet.type == WalletType.bitcoin && bitcoin!.isTestnet(wallet);
diff --git a/lib/view_model/settings/connection_sync_view_model.dart b/lib/view_model/settings/connection_sync_view_model.dart
new file mode 100644
index 00000000..b48ae323
--- /dev/null
+++ b/lib/view_model/settings/connection_sync_view_model.dart
@@ -0,0 +1,236 @@
+import 'dart:async';
+
+import 'package:cake_wallet/entities/exchange_api_mode.dart';
+import 'package:cake_wallet/entities/fiat_api_mode.dart';
+import 'package:cake_wallet/evm/evm.dart';
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/reactions/wallet_connect.dart';
+import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
+import 'package:cake_wallet/store/app_store.dart';
+import 'package:cake_wallet/store/settings_store.dart';
+import 'package:cake_wallet/tron/tron.dart';
+import 'package:cake_wallet/utils/show_pop_up.dart';
+import 'package:cake_wallet/utils/tor.dart';
+import 'package:cw_core/balance.dart';
+import 'package:cw_core/transaction_history.dart';
+import 'package:cw_core/transaction_info.dart';
+import 'package:cw_core/wallet_base.dart';
+import 'package:cw_core/wallet_type.dart';
+import 'package:flutter/material.dart';
+import 'package:mobx/mobx.dart';
+
+part 'connection_sync_view_model.g.dart';
+
+class ConnectionSyncViewModel = ConnectionSyncViewModelBase with _$ConnectionSyncViewModel;
+
+abstract class ConnectionSyncViewModelBase with Store {
+ ConnectionSyncViewModelBase(this._settingsStore, this._wallet);
+
+ final SettingsStore _settingsStore;
+ final WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo> _wallet;
+
+ @computed
+ bool get lookupTwitter => _settingsStore.lookupsTwitter;
+
+ @computed
+ bool get lookupsZanoAlias => _settingsStore.lookupsZanoAlias;
+
+ @computed
+ bool get looksUpMastodon => _settingsStore.lookupsMastodon;
+
+ @computed
+ bool get looksUpYatService => _settingsStore.lookupsYatService;
+
+ @computed
+ bool get looksUpUnstoppableDomains => _settingsStore.lookupsUnstoppableDomains;
+
+ @computed
+ bool get looksUpOpenAlias => _settingsStore.lookupsOpenAlias;
+
+ @computed
+ bool get looksUpENS => _settingsStore.lookupsENS;
+
+ @computed
+ bool get looksUpWellKnown => _settingsStore.lookupsWellKnown;
+
+ @computed
+ ExchangeApiMode get exchangeStatus => _settingsStore.exchangeStatus;
+
+ @computed
+ FiatApiMode get fiatApiMode => _settingsStore.fiatApiMode;
+
+ @computed
+ bool get disableAutomaticExchangeStatusUpdates =>
+ _settingsStore.disableAutomaticExchangeStatusUpdates;
+
+ @computed
+ bool get builtinTor => _settingsStore.currentBuiltinTor;
+
+
+ @computed
+ bool get hasPowNodes => [WalletType.nano, WalletType.banano].contains(_wallet.type);
+
+ @computed
+ bool get useMempoolFeeAPI => _settingsStore.useMempoolFeeAPI;
+
+ @computed
+ bool get canUseMempoolFeeAPI => _wallet.type == WalletType.bitcoin;
+
+ @computed
+ bool get useBlinkProtection => _settingsStore.useBlinkProtection;
+
+ bool get canUseBlinkProtection => canSupportBlinkProtection(_wallet.chainId);
+
+ @computed
+ bool get useEtherscan => _settingsStore.useEtherscan;
+
+ @computed
+ bool get usePolygonScan => _settingsStore.usePolygonScan;
+
+ @computed
+ bool get useBaseScan => _settingsStore.useBaseScan;
+
+ @computed
+ bool get useArbiScan => _settingsStore.useArbiScan;
+
+ @computed
+ bool get useBscScan => _settingsStore.useBscScan;
+
+ @computed
+ bool get useTronGrid => _settingsStore.useTronGrid;
+
+ @computed
+ bool get canUseEtherscan => _wallet.chainId == 1;
+
+ @computed
+ bool get canUsePolygonScan => _wallet.chainId == 137;
+
+ @computed
+ bool get canUseBaseScan => _wallet.chainId == 8453;
+
+ @computed
+ bool get canUseArbiScan => _wallet.chainId == 42161;
+
+ @computed
+ bool get canUseBscScan => _wallet.chainId == 56;
+
+ @computed
+ bool get canUseTronGrid => _wallet.type == WalletType.tron;
+
+ @action
+ void setLookupsTwitter(bool value) => _settingsStore.lookupsTwitter = value;
+
+ @action
+ void setLookupsZanoAlias(bool value) => _settingsStore.lookupsZanoAlias = value;
+
+ @action
+ void setLookupsMastodon(bool value) => _settingsStore.lookupsMastodon = value;
+
+ @action
+ void setLookupsENS(bool value) => _settingsStore.lookupsENS = value;
+
+ @action
+ void setLookupsWellKnown(bool value) => _settingsStore.lookupsWellKnown = value;
+
+ @action
+ void setLookupsYatService(bool value) => _settingsStore.lookupsYatService = value;
+
+ @action
+ void setLookupsUnstoppableDomains(bool value) => _settingsStore.lookupsUnstoppableDomains = value;
+
+ @action
+ void setLookupsOpenAlias(bool value) => _settingsStore.lookupsOpenAlias = value;
+
+ @action
+ void setUseMempoolFeeAPI(bool value) => _settingsStore.useMempoolFeeAPI = value;
+
+ @action
+ void setDisableAutomaticExchangeStatusUpdates(bool value) =>
+ _settingsStore.disableAutomaticExchangeStatusUpdates = value;
+
+ @action
+ void setFiatMode(FiatApiMode fiatApiMode) => _settingsStore.fiatApiMode = fiatApiMode;
+
+ @action
+ void setExchangeApiMode(ExchangeApiMode value) => _settingsStore.exchangeStatus = value;
+
+ @action
+ void setUseBlinkProtection(bool value) => _settingsStore.useBlinkProtection = value;
+
+ @action
+ void setUseEtherscan(bool value) {
+ _settingsStore.useEtherscan = value;
+ evm!.updateScanProviderUsageState(_wallet, value);
+ }
+
+ @action
+ void setUsePolygonScan(bool value) {
+ _settingsStore.usePolygonScan = value;
+ evm!.updateScanProviderUsageState(_wallet, value);
+ }
+
+ @action
+ void setUseBaseScan(bool value) {
+ _settingsStore.useBaseScan = value;
+ evm!.updateScanProviderUsageState(_wallet, value);
+ }
+
+ @action
+ void setUseTronGrid(bool value) {
+ _settingsStore.useTronGrid = value;
+ tron!.updateTronGridUsageState(_wallet, value);
+ }
+
+ @action
+ void setUseArbiScan(bool value) {
+ _settingsStore.useArbiScan = value;
+ evm!.updateScanProviderUsageState(_wallet, value);
+ }
+
+ @action
+ void setUseBscScan(bool value) {
+ _settingsStore.useBscScan = value;
+ evm!.updateScanProviderUsageState(_wallet, value);
+ }
+
+ @action
+ void setBuiltinTor(bool value, BuildContext context) {
+ if (value) {
+ unawaited(
+ showPopUp<bool>(
+ context: context,
+ builder: (BuildContext context) {
+ return AlertWithOneAction(
+ alertTitle: S.of(context).tor_connection,
+ alertContent: S.of(context).tor_experimental,
+ buttonText: S.of(context).ok,
+ buttonAction: () => Navigator.of(context).pop(true),
+ );
+ },
+ ),
+ );
+ }
+ _settingsStore.currentBuiltinTor = value;
+ if (value) {
+ unawaited(ensureTorStarted(context: context).then((_) async {
+ if (_settingsStore.currentBuiltinTor == false) return;
+ int? chainId;
+ if (isEVMCompatibleChain(_wallet.type)) {
+ chainId = evm!.getSelectedChainId(_wallet);
+ }
+ await _wallet.connectToNode(
+ node: _settingsStore.getCurrentNode(_wallet.type, chainId: chainId));
+ }));
+ } else {
+ unawaited(ensureTorStopped(context: context).then((_) async {
+ if (_settingsStore.currentBuiltinTor == true) return;
+ int? chainId;
+ if (isEVMCompatibleChain(_wallet.type)) {
+ chainId = evm!.getSelectedChainId(_wallet);
+ }
+ await _wallet.connectToNode(
+ node: _settingsStore.getCurrentNode(_wallet.type, chainId: chainId));
+ }));
+ }
+ }
+}
diff --git a/lib/view_model/settings/display_settings_view_model.dart b/lib/view_model/settings/display_settings_view_model.dart
index 7bc2cc4f..ab6c8f9c 100644
--- a/lib/view_model/settings/display_settings_view_model.dart
+++ b/lib/view_model/settings/display_settings_view_model.dart
@@ -24,6 +24,9 @@ abstract class DisplaySettingsViewModelBase with Store {
SettingsStore get _settingsStore => _appStore.settingsStore;
final ThemeStore _themeStore;
+ @computed
+ bool get disableTradeOption => _settingsStore.disableTradeOption;
+
@computed
FiatCurrency get fiatCurrency => _settingsStore.fiatCurrency;
@@ -110,6 +113,9 @@ abstract class DisplaySettingsViewModelBase with Store {
return [];
}
+ @action
+ void setDisableTradeOption(bool value) => _settingsStore.disableTradeOption = value;
+
@action
void setBalanceDisplayMode(BalanceDisplayMode value) => _settingsStore.balanceDisplayMode = value;
@@ -246,18 +252,18 @@ abstract class DisplaySettingsViewModelBase with Store {
String getImageForTheme(MaterialThemeBase theme) {
switch (theme.title) {
case 'Dark Theme':
- return 'assets/images/dark.svg';
+ return 'assets/new-ui/dark.svg';
case 'Light Theme':
- return 'assets/images/light.svg';
+ return 'assets/new-ui/light.svg';
case 'Black Theme (Cake Primary)':
case 'Black Theme (BCH Green)':
case 'Black Theme (Bitcoin Yellow)':
case 'Black Theme (Monero Orange)':
case 'Black Theme (Tron Red)':
case 'Black Theme (Frosting Purple)':
- return 'assets/images/black_accent.svg';
+ return 'assets/new-ui/black_accent.svg';
default:
- return 'assets/images/dark.svg';
+ return 'assets/new-ui/dark.svg';
}
}
}
diff --git a/lib/view_model/settings/other_settings_view_model.dart b/lib/view_model/settings/other_settings_view_model.dart
index b94e7f2c..8741c265 100644
--- a/lib/view_model/settings/other_settings_view_model.dart
+++ b/lib/view_model/settings/other_settings_view_model.dart
@@ -1,6 +1,7 @@
import 'dart:io';
import 'package:cake_wallet/bitcoin/bitcoin.dart';
+import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
import 'package:cake_wallet/entities/priority_for_wallet_type.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/utils/package_info.dart';
@@ -57,6 +58,33 @@ abstract class OtherSettingsViewModelBase with Store {
return priority;
}
+ @computed
+ bool get isAutoGenerateSubaddressesEnabled =>
+ _settingsStore.autoGenerateSubaddressStatus != AutoGenerateSubaddressStatus.disabled;
+
+ @action
+ void setAutoGenerateSubaddresses(bool value) {
+ _wallet.isEnabledAutoGenerateSubaddress = value;
+ _settingsStore.autoGenerateSubaddressStatus =
+ value ? AutoGenerateSubaddressStatus.enabled : AutoGenerateSubaddressStatus.disabled;
+ }
+
+ bool get isAutoGenerateSubaddressesVisible => [
+ WalletType.monero,
+ WalletType.wownero,
+ WalletType.bitcoin,
+ WalletType.litecoin,
+ WalletType.bitcoinCash,
+ WalletType.dogecoin,
+ WalletType.decred
+ ].contains(_wallet.type);
+
+ @computed
+ bool get isMoneroWallet => _wallet.type == WalletType.monero;
+
+ @computed
+ bool get shouldSaveRecipientAddress => _settingsStore.shouldSaveRecipientAddress;
+
@computed
bool get changeRepresentativeEnabled =>
[WalletType.nano, WalletType.banano].contains(_wallet.type);
@@ -127,6 +155,10 @@ abstract class OtherSettingsViewModelBase with Store {
@computed
double get customBitcoinFeeRate => _settingsStore.customBitcoinFeeRate.toDouble();
+ @action
+ void setShouldSaveRecipientAddress(bool value) =>
+ _settingsStore.shouldSaveRecipientAddress = value;
+
int? get customPriorityItemIndex {
final priorities = priorityForWalletType(walletType);
final customItem = priorities
diff --git a/lib/view_model/settings/privacy_settings_view_model.dart b/lib/view_model/settings/privacy_settings_view_model.dart
index 1b99d664..d77eb668 100644
--- a/lib/view_model/settings/privacy_settings_view_model.dart
+++ b/lib/view_model/settings/privacy_settings_view_model.dart
@@ -1,10 +1,6 @@
import 'package:cake_wallet/bitcoin/bitcoin.dart';
import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
-import 'package:cake_wallet/entities/exchange_api_mode.dart';
-import 'package:cake_wallet/evm/evm.dart';
import 'package:cake_wallet/store/settings_store.dart';
-import 'package:cake_wallet/tron/tron.dart';
-import 'package:cake_wallet/reactions/wallet_connect.dart';
import 'package:cake_wallet/utils/device_info.dart';
import 'package:cw_core/balance.dart';
import 'package:cw_core/transaction_history.dart';
@@ -12,7 +8,6 @@ import 'package:cw_core/transaction_info.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:mobx/mobx.dart';
-import 'package:cake_wallet/entities/fiat_api_mode.dart';
part 'privacy_settings_view_model.g.dart';
@@ -25,7 +20,10 @@ abstract class PrivacySettingsViewModelBase with Store {
final WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo> _wallet;
@computed
- ExchangeApiMode get exchangeStatus => _settingsStore.exchangeStatus;
+ bool get isBitcoin => _wallet.type == WalletType.bitcoin;
+
+ @computed
+ bool get isLitecoin => _wallet.type == WalletType.litecoin;
@computed
bool get isAutoGenerateSubaddressesEnabled =>
@@ -65,9 +63,6 @@ abstract class PrivacySettingsViewModelBase with Store {
@computed
bool get shouldSaveRecipientAddress => _settingsStore.shouldSaveRecipientAddress;
- @computed
- FiatApiMode get fiatApiMode => _settingsStore.fiatApiMode;
-
@computed
bool get isAppSecure => _settingsStore.isAppSecure;
@@ -81,32 +76,6 @@ abstract class PrivacySettingsViewModelBase with Store {
@computed
bool get disableBulletin => _settingsStore.disableBulletin;
- @computed
- bool get useEtherscan => _settingsStore.useEtherscan;
-
- @computed
- bool get usePolygonScan => _settingsStore.usePolygonScan;
-
- @computed
- bool get useBaseScan => _settingsStore.useBaseScan;
-
- @computed
- bool get useArbiScan => _settingsStore.useArbiScan;
-
- @computed
- bool get useBscScan => _settingsStore.useBscScan;
-
- @computed
- bool get useTronGrid => _settingsStore.useTronGrid;
-
- @computed
- bool get useMempoolFeeAPI => _settingsStore.useMempoolFeeAPI;
-
- @computed
- bool get useBlinkProtection => _settingsStore.useBlinkProtection;
-
- bool get canUseBlinkProtection => canSupportBlinkProtection(_wallet.chainId);
-
@computed
bool get lookupTwitter => _settingsStore.lookupsTwitter;
@@ -135,36 +104,18 @@ abstract class PrivacySettingsViewModelBase with Store {
bool get usePayjoin => _settingsStore.usePayjoin;
@computed
- bool get useLightning => _wallet.type == WalletType.bitcoin && bitcoin!.useLightning(_wallet);
-
- bool get canUseEtherscan => _wallet.chainId == 1;
-
- bool get canUsePolygonScan => _wallet.chainId == 137;
-
- bool get canUseBaseScan => _wallet.chainId == 8453;
-
- bool get canUseArbiScan => _wallet.chainId == 42161;
-
- bool get canUseBscScan => _wallet.chainId == 56;
-
- bool get canUseTronGrid => _wallet.type == WalletType.tron;
-
- bool get canUseMempoolFeeAPI => _wallet.type == WalletType.bitcoin;
-
bool get canUsePayjoin => _wallet.type == WalletType.bitcoin && DeviceInfo.instance.isMobile;
+ @computed
bool get canUseLightning => _wallet.type == WalletType.bitcoin;
+ @computed
+ bool get useLightning => _wallet.type == WalletType.bitcoin && bitcoin!.useLightning(_wallet);
+
@action
void setShouldSaveRecipientAddress(bool value) =>
_settingsStore.shouldSaveRecipientAddress = value;
- @action
- void setExchangeApiMode(ExchangeApiMode value) => _settingsStore.exchangeStatus = value;
-
- @action
- void setFiatMode(FiatApiMode fiatApiMode) => _settingsStore.fiatApiMode = fiatApiMode;
-
@action
void setIsAppSecure(bool value) => _settingsStore.isAppSecure = value;
@@ -178,66 +129,6 @@ abstract class PrivacySettingsViewModelBase with Store {
@action
void setDisableBulletin(bool value) => _settingsStore.disableBulletin = value;
- @action
- void setLookupsTwitter(bool value) => _settingsStore.lookupsTwitter = value;
-
- @action
- void setLookupsZanoAlias(bool value) => _settingsStore.lookupsZanoAlias = value;
-
- @action
- void setLookupsMastodon(bool value) => _settingsStore.lookupsMastodon = value;
-
- @action
- void setLookupsENS(bool value) => _settingsStore.lookupsENS = value;
-
- @action
- void setLookupsWellKnown(bool value) => _settingsStore.lookupsWellKnown = value;
-
- @action
- void setLookupsYatService(bool value) => _settingsStore.lookupsYatService = value;
-
- @action
- void setLookupsUnstoppableDomains(bool value) => _settingsStore.lookupsUnstoppableDomains = value;
-
- @action
- void setLookupsOpenAlias(bool value) => _settingsStore.lookupsOpenAlias = value;
-
- @action
- void setUseEtherscan(bool value) {
- _settingsStore.useEtherscan = value;
- evm!.updateScanProviderUsageState(_wallet, value);
- }
-
- @action
- void setUsePolygonScan(bool value) {
- _settingsStore.usePolygonScan = value;
- evm!.updateScanProviderUsageState(_wallet, value);
- }
-
- @action
- void setUseBaseScan(bool value) {
- _settingsStore.useBaseScan = value;
- evm!.updateScanProviderUsageState(_wallet, value);
- }
-
- @action
- void setUseTronGrid(bool value) {
- _settingsStore.useTronGrid = value;
- tron!.updateTronGridUsageState(_wallet, value);
- }
-
- @action
- void setUseArbiScan(bool value) {
- _settingsStore.useArbiScan = value;
- evm!.updateScanProviderUsageState(_wallet, value);
- }
-
- @action
- void setUseBscScan(bool value) {
- _settingsStore.useBscScan = value;
- evm!.updateScanProviderUsageState(_wallet, value);
- }
-
@action
void setUseMempoolFeeAPI(bool value) => _settingsStore.useMempoolFeeAPI = value;
diff --git a/lib/view_model/settings/security_settings_view_model.dart b/lib/view_model/settings/security_settings_view_model.dart
index c7ea6107..2c417587 100644
--- a/lib/view_model/settings/security_settings_view_model.dart
+++ b/lib/view_model/settings/security_settings_view_model.dart
@@ -15,6 +15,9 @@ abstract class SecuritySettingsViewModelBase with Store {
final SettingsStore _settingsStore;
final AuthService _authService;
+ @computed
+ bool get isAppSecure => _settingsStore.isAppSecure;
+
@computed
bool get allowBiometricalAuthentication => _settingsStore.allowBiometricalAuthentication;
@@ -36,6 +39,9 @@ abstract class SecuritySettingsViewModelBase with Store {
return await _biometricAuth.canCheckBiometrics() && await _biometricAuth.isAuthenticated();
}
+ @action
+ void setIsAppSecure(bool value) => _settingsStore.isAppSecure = value;
+
@action
void setAllowBiometricalAuthentication(bool value) =>
_settingsStore.allowBiometricalAuthentication = value;
diff --git a/res/pictures/black_accent.svg b/res/pictures/black_accent.svg
new file mode 100644
index 00000000..7e22d3b1
--- /dev/null
+++ b/res/pictures/black_accent.svg
@@ -0,0 +1,13 @@
+<svg width="92" height="173" viewBox="0 0 92 173" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect width="92" height="173" rx="10" fill="#131314"/>
+<rect x="16" y="8" width="59" height="9" rx="4.5" fill="#211F20"/>
+<rect x="8" y="152" width="75" height="14" rx="7" fill="#211F20"/>
+<rect x="8" y="37" width="75" height="30" rx="4" fill="#211F20"/>
+<rect x="10" y="31" width="16" height="3" fill="#B4B4B4"/>
+<rect x="12" y="41" width="34" height="3" fill="#B4B4B4"/>
+<rect x="12" y="46" width="34" height="3" fill="#B4B4B4"/>
+<rect x="12" y="51" width="26" height="3" fill="#B4B4B4"/>
+<rect x="12" y="56" width="26" height="3" fill="#B4B4B4"/>
+<rect x="71" y="54" width="8" height="3" fill="#B4B4B4"/>
+<rect x="71" y="44" width="8" height="8" rx="4" fill="#52B6F0"/>
+</svg>
diff --git a/res/pictures/chooser.svg b/res/pictures/chooser.svg
index ca5c07d4..8e7c24bf 100644
--- a/res/pictures/chooser.svg
+++ b/res/pictures/chooser.svg
@@ -1,10 +1,3 @@
-<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
- <g clip-path="url(#clip0_14441_461975)">
- <path d="M8.51392 11.9985L5 8.48462L5.66456 7.82006L8.51392 10.6576L11.3633 7.82006L12.0278 8.48462L8.51392 11.9985ZM5.67404 4.16738L5 3.51245L8.51392 -0.00146484L12.0278 3.51245L11.3538 4.16738L8.51392 1.33947L5.67404 4.16738Z" fill="white"/>
- </g>
- <defs>
- <clipPath id="clip0_14441_461975">
- <rect width="12" height="12" fill="white"/>
- </clipPath>
- </defs>
+<svg width="8" height="13" viewBox="0 0 8 13" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M3.76917 12.8717L0 9.1025L0.712833 8.38967L3.76917 11.4333L6.8255 8.38967L7.53833 9.1025L3.76917 12.8717ZM0.723 4.47167L0 3.76917L3.76917 0L7.53833 3.76917L6.81533 4.47167L3.76917 1.43833L0.723 4.47167Z" fill="#8C9FBB"/>
</svg>
diff --git a/res/pictures/dark.svg b/res/pictures/dark.svg
new file mode 100644
index 00000000..20baf68f
--- /dev/null
+++ b/res/pictures/dark.svg
@@ -0,0 +1,13 @@
+<svg width="92" height="173" viewBox="0 0 92 173" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect width="92" height="173" rx="10" fill="#1B284A"/>
+<rect x="16" y="8" width="59" height="9" rx="4.5" fill="#233461"/>
+<rect x="8" y="152" width="75" height="14" rx="7" fill="#233461"/>
+<rect x="8" y="37" width="75" height="30" rx="4" fill="#233461"/>
+<rect x="10" y="31" width="16" height="3" fill="#8C9FBB"/>
+<rect x="12" y="41" width="34" height="3" fill="#8C9FBB"/>
+<rect x="12" y="46" width="34" height="3" fill="#8C9FBB"/>
+<rect x="12" y="51" width="26" height="3" fill="#8C9FBB"/>
+<rect x="12" y="56" width="26" height="3" fill="#8C9FBB"/>
+<rect x="71" y="54" width="8" height="3" fill="#8C9FBB"/>
+<rect x="71" y="44" width="8" height="8" rx="4" fill="#91B0FF"/>
+</svg>
diff --git a/res/pictures/light.svg b/res/pictures/light.svg
new file mode 100644
index 00000000..183a13fd
--- /dev/null
+++ b/res/pictures/light.svg
@@ -0,0 +1,13 @@
+<svg width="92" height="173" viewBox="0 0 92 173" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect width="92" height="173" rx="10" fill="#EFEFF8"/>
+<rect x="16" y="8" width="59" height="9" rx="4.5" fill="#FBFBFD"/>
+<rect x="8" y="152" width="75" height="14" rx="7" fill="#FBFBFD"/>
+<rect x="8" y="37" width="75" height="30" rx="4" fill="#FBFBFD"/>
+<rect x="10" y="31" width="16" height="3" fill="#6C6772"/>
+<rect x="12" y="41" width="34" height="3" fill="#6C6772"/>
+<rect x="12" y="46" width="34" height="3" fill="#6C6772"/>
+<rect x="12" y="51" width="26" height="3" fill="#6C6772"/>
+<rect x="12" y="56" width="26" height="3" fill="#6C6772"/>
+<rect x="71" y="54" width="8" height="3" fill="#6C6772"/>
+<rect x="71" y="44" width="8" height="8" rx="4" fill="#4EBEFF"/>
+</svg>
diff --git a/res/pictures/settings_row_icons/privacy.svg b/res/pictures/settings_row_icons/privacy.svg
index 763bfbaf..3a8a8503 100644
--- a/res/pictures/settings_row_icons/privacy.svg
+++ b/res/pictures/settings_row_icons/privacy.svg
@@ -1,40 +1,35 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
- <g clip-path="url(#clip0_16845_60754)">
- <g clip-path="url(#clip1_16845_60754)">
- <path d="M0 8C0 5.19974 0 3.79961 0.544967 2.73005C1.02433 1.78924 1.78924 1.02433 2.73005 0.544967C3.79961 0 5.19974 0 8 0H16C18.8003 0 20.2004 0 21.27 0.544967C22.2108 1.02433 22.9757 1.78924 23.455 2.73005C24 3.79961 24 5.19974 24 8V16C24 18.8003 24 20.2004 23.455 21.27C22.9757 22.2108 22.2108 22.9757 21.27 23.455C20.2004 24 18.8003 24 16 24H8C5.19974 24 3.79961 24 2.73005 23.455C1.78924 22.9757 1.02433 22.2108 0.544967 21.27C0 20.2004 0 18.8003 0 16V8Z" fill="url(#paint0_linear_16845_60754)"/>
- <path d="M0 8C0 5.19974 0 3.79961 0.544967 2.73005C1.02433 1.78924 1.78924 1.02433 2.73005 0.544967C3.79961 0 5.19974 0 8 0H16C18.8003 0 20.2004 0 21.27 0.544967C22.2108 1.02433 22.9757 1.78924 23.455 2.73005C24 3.79961 24 5.19974 24 8V16C24 18.8003 24 20.2004 23.455 21.27C22.9757 22.2108 22.2108 22.9757 21.27 23.455C20.2004 24 18.8003 24 16 24H8C5.19974 24 3.79961 24 2.73005 23.455C1.78924 22.9757 1.02433 22.2108 0.544967 21.27C0 20.2004 0 18.8003 0 16V8Z" fill="url(#paint1_linear_16845_60754)"/>
- <path d="M11.8691 3.35876C14.2163 3.35876 16.1192 5.26162 16.1192 7.60881V9.85891H17.4943C18.1155 9.85897 18.6191 10.3625 18.6191 10.9838V18.2337C18.6191 18.855 18.1155 19.3586 17.4943 19.3586H6.24403C5.62276 19.3586 5.11914 18.855 5.11914 18.2337V10.9838C5.11916 10.3625 5.62278 9.85897 6.24403 9.85891H7.61908V7.60881C7.6191 5.26165 9.52197 3.3588 11.8691 3.35876ZM11.8691 13.0787C11.049 13.0787 10.384 13.7436 10.384 14.5638C10.384 15.3839 11.049 16.0489 11.8691 16.0489C12.6893 16.0489 13.3543 15.3839 13.3543 14.5638C13.3543 13.7436 12.6893 13.0787 11.8691 13.0787ZM11.8691 5.35871C10.6265 5.35875 9.61938 6.36621 9.61936 7.60881V9.85891H14.1193V7.60881C14.1192 6.36619 13.1118 5.35871 11.8691 5.35871Z" fill="white"/>
- <path d="M11.8691 3.35876C14.2163 3.35876 16.1192 5.26162 16.1192 7.60881V9.85891H17.4943C18.1155 9.85897 18.6191 10.3625 18.6191 10.9838V18.2337C18.6191 18.855 18.1155 19.3586 17.4943 19.3586H6.24403C5.62276 19.3586 5.11914 18.855 5.11914 18.2337V10.9838C5.11916 10.3625 5.62278 9.85897 6.24403 9.85891H7.61908V7.60881C7.6191 5.26165 9.52197 3.3588 11.8691 3.35876ZM11.8691 13.0787C11.049 13.0787 10.384 13.7436 10.384 14.5638C10.384 15.3839 11.049 16.0489 11.8691 16.0489C12.6893 16.0489 13.3543 15.3839 13.3543 14.5638C13.3543 13.7436 12.6893 13.0787 11.8691 13.0787ZM11.8691 5.35871C10.6265 5.35875 9.61938 6.36621 9.61936 7.60881V9.85891H14.1193V7.60881C14.1192 6.36619 13.1118 5.35871 11.8691 5.35871Z" fill="url(#paint2_linear_16845_60754)"/>
- <path d="M11.8691 3.35876C14.2163 3.35876 16.1192 5.26162 16.1192 7.60881V9.85891H17.4943C18.1155 9.85897 18.6191 10.3625 18.6191 10.9838V18.2337C18.6191 18.855 18.1155 19.3586 17.4943 19.3586H6.24403C5.62276 19.3586 5.11914 18.855 5.11914 18.2337V10.9838C5.11916 10.3625 5.62278 9.85897 6.24403 9.85891H7.61908V7.60881C7.6191 5.26165 9.52197 3.3588 11.8691 3.35876ZM11.8691 13.0787C11.049 13.0787 10.384 13.7436 10.384 14.5638C10.384 15.3839 11.049 16.0489 11.8691 16.0489C12.6893 16.0489 13.3543 15.3839 13.3543 14.5638C13.3543 13.7436 12.6893 13.0787 11.8691 13.0787ZM11.8691 5.35871C10.6265 5.35875 9.61938 6.36621 9.61936 7.60881V9.85891H14.1193V7.60881C14.1192 6.36619 13.1118 5.35871 11.8691 5.35871Z" fill="url(#paint3_linear_16845_60754)"/>
- <path d="M11.8691 3.35876C14.2163 3.35876 16.1192 5.26162 16.1192 7.60881V9.85891H17.4943C18.1155 9.85897 18.6191 10.3625 18.6191 10.9838V18.2337C18.6191 18.855 18.1155 19.3586 17.4943 19.3586H6.24403C5.62276 19.3586 5.11914 18.855 5.11914 18.2337V10.9838C5.11916 10.3625 5.62278 9.85897 6.24403 9.85891H7.61908V7.60881C7.6191 5.26165 9.52197 3.3588 11.8691 3.35876ZM11.8691 13.0787C11.049 13.0787 10.384 13.7436 10.384 14.5638C10.384 15.3839 11.049 16.0489 11.8691 16.0489C12.6893 16.0489 13.3543 15.3839 13.3543 14.5638C13.3543 13.7436 12.6893 13.0787 11.8691 13.0787ZM11.8691 5.35871C10.6265 5.35875 9.61938 6.36621 9.61936 7.60881V9.85891H14.1193V7.60881C14.1192 6.36619 13.1118 5.35871 11.8691 5.35871Z" fill="url(#paint4_linear_16845_60754)"/>
- </g>
- </g>
- <defs>
- <linearGradient id="paint0_linear_16845_60754" x1="12" y1="0" x2="12" y2="24" gradientUnits="userSpaceOnUse">
- <stop stop-color="#8F8F8F"/>
- <stop offset="1" stop-color="#6D6D6D"/>
- </linearGradient>
- <linearGradient id="paint1_linear_16845_60754" x1="12" y1="0" x2="12" y2="24" gradientUnits="userSpaceOnUse">
- <stop stop-color="#F7931A"/>
- <stop offset="1" stop-color="#F67300"/>
- </linearGradient>
- <linearGradient id="paint2_linear_16845_60754" x1="11.8691" y1="3.35876" x2="11.8691" y2="19.3586" gradientUnits="userSpaceOnUse">
- <stop stop-color="white"/>
- <stop offset="1" stop-color="#A4B8FF"/>
- </linearGradient>
- <linearGradient id="paint3_linear_16845_60754" x1="11.8691" y1="3.35876" x2="11.8691" y2="19.3586" gradientUnits="userSpaceOnUse">
- <stop stop-color="white"/>
- <stop offset="1" stop-color="#A4CEFF"/>
- </linearGradient>
- <linearGradient id="paint4_linear_16845_60754" x1="11.8691" y1="3.35876" x2="11.8691" y2="19.3586" gradientUnits="userSpaceOnUse">
- <stop stop-color="#5F330B"/>
- <stop offset="1" stop-color="#462100"/>
- </linearGradient>
- <clipPath id="clip0_16845_60754">
- <rect width="24" height="24" fill="white"/>
- </clipPath>
- <clipPath id="clip1_16845_60754">
- <rect width="24" height="24" fill="white"/>
- </clipPath>
- </defs>
+<g clip-path="url(#clip0_16529_391320)">
+<path d="M0 8C0 5.19974 0 3.79961 0.544967 2.73005C1.02433 1.78924 1.78924 1.02433 2.73005 0.544967C3.79961 0 5.19974 0 8 0H16C18.8003 0 20.2004 0 21.27 0.544967C22.2108 1.02433 22.9757 1.78924 23.455 2.73005C24 3.79961 24 5.19974 24 8V16C24 18.8003 24 20.2004 23.455 21.27C22.9757 22.2108 22.2108 22.9757 21.27 23.455C20.2004 24 18.8003 24 16 24H8C5.19974 24 3.79961 24 2.73005 23.455C1.78924 22.9757 1.02433 22.2108 0.544967 21.27C0 20.2004 0 18.8003 0 16V8Z" fill="url(#paint0_linear_16529_391320)"/>
+<path d="M0 8C0 5.19974 0 3.79961 0.544967 2.73005C1.02433 1.78924 1.78924 1.02433 2.73005 0.544967C3.79961 0 5.19974 0 8 0H16C18.8003 0 20.2004 0 21.27 0.544967C22.2108 1.02433 22.9757 1.78924 23.455 2.73005C24 3.79961 24 5.19974 24 8V16C24 18.8003 24 20.2004 23.455 21.27C22.9757 22.2108 22.2108 22.9757 21.27 23.455C20.2004 24 18.8003 24 16 24H8C5.19974 24 3.79961 24 2.73005 23.455C1.78924 22.9757 1.02433 22.2108 0.544967 21.27C0 20.2004 0 18.8003 0 16V8Z" fill="url(#paint1_linear_16529_391320)"/>
+<path d="M11.8711 3.3584C14.2183 3.3584 16.1211 5.26126 16.1212 7.60844V9.85854H17.4962C18.1175 9.8586 18.6211 10.3622 18.6211 10.9834V18.2334C18.6211 18.8547 18.1175 19.3582 17.4962 19.3583H6.24598C5.62471 19.3582 5.12109 18.8547 5.12109 18.2334V10.9834C5.12112 10.3622 5.62473 9.8586 6.24598 9.85854H7.62103V7.60844C7.62105 5.26128 9.52393 3.35844 11.8711 3.3584ZM11.8711 13.0783C11.051 13.0783 10.386 13.7433 10.386 14.5634C10.386 15.3835 11.051 16.0485 11.8711 16.0485C12.6912 16.0485 13.3562 15.3835 13.3562 14.5634C13.3562 13.7433 12.6912 13.0783 11.8711 13.0783ZM11.8711 5.35834C10.6285 5.35838 9.62133 6.36584 9.62131 7.60844V9.85854H14.1212V7.60844C14.1212 6.36582 13.1137 5.35834 11.8711 5.35834Z" fill="white"/>
+<path d="M11.8711 3.3584C14.2183 3.3584 16.1211 5.26126 16.1212 7.60844V9.85854H17.4962C18.1175 9.8586 18.6211 10.3622 18.6211 10.9834V18.2334C18.6211 18.8547 18.1175 19.3582 17.4962 19.3583H6.24598C5.62471 19.3582 5.12109 18.8547 5.12109 18.2334V10.9834C5.12112 10.3622 5.62473 9.8586 6.24598 9.85854H7.62103V7.60844C7.62105 5.26128 9.52393 3.35844 11.8711 3.3584ZM11.8711 13.0783C11.051 13.0783 10.386 13.7433 10.386 14.5634C10.386 15.3835 11.051 16.0485 11.8711 16.0485C12.6912 16.0485 13.3562 15.3835 13.3562 14.5634C13.3562 13.7433 12.6912 13.0783 11.8711 13.0783ZM11.8711 5.35834C10.6285 5.35838 9.62133 6.36584 9.62131 7.60844V9.85854H14.1212V7.60844C14.1212 6.36582 13.1137 5.35834 11.8711 5.35834Z" fill="url(#paint2_linear_16529_391320)"/>
+<path d="M11.8711 3.3584C14.2183 3.3584 16.1211 5.26126 16.1212 7.60844V9.85854H17.4962C18.1175 9.8586 18.6211 10.3622 18.6211 10.9834V18.2334C18.6211 18.8547 18.1175 19.3582 17.4962 19.3583H6.24598C5.62471 19.3582 5.12109 18.8547 5.12109 18.2334V10.9834C5.12112 10.3622 5.62473 9.8586 6.24598 9.85854H7.62103V7.60844C7.62105 5.26128 9.52393 3.35844 11.8711 3.3584ZM11.8711 13.0783C11.051 13.0783 10.386 13.7433 10.386 14.5634C10.386 15.3835 11.051 16.0485 11.8711 16.0485C12.6912 16.0485 13.3562 15.3835 13.3562 14.5634C13.3562 13.7433 12.6912 13.0783 11.8711 13.0783ZM11.8711 5.35834C10.6285 5.35838 9.62133 6.36584 9.62131 7.60844V9.85854H14.1212V7.60844C14.1212 6.36582 13.1137 5.35834 11.8711 5.35834Z" fill="url(#paint3_linear_16529_391320)"/>
+<path d="M11.8711 3.3584C14.2183 3.3584 16.1211 5.26126 16.1212 7.60844V9.85854H17.4962C18.1175 9.8586 18.6211 10.3622 18.6211 10.9834V18.2334C18.6211 18.8547 18.1175 19.3582 17.4962 19.3583H6.24598C5.62471 19.3582 5.12109 18.8547 5.12109 18.2334V10.9834C5.12112 10.3622 5.62473 9.8586 6.24598 9.85854H7.62103V7.60844C7.62105 5.26128 9.52393 3.35844 11.8711 3.3584ZM11.8711 13.0783C11.051 13.0783 10.386 13.7433 10.386 14.5634C10.386 15.3835 11.051 16.0485 11.8711 16.0485C12.6912 16.0485 13.3562 15.3835 13.3562 14.5634C13.3562 13.7433 12.6912 13.0783 11.8711 13.0783ZM11.8711 5.35834C10.6285 5.35838 9.62133 6.36584 9.62131 7.60844V9.85854H14.1212V7.60844C14.1212 6.36582 13.1137 5.35834 11.8711 5.35834Z" fill="url(#paint4_linear_16529_391320)"/>
+</g>
+<defs>
+<linearGradient id="paint0_linear_16529_391320" x1="12" y1="0" x2="12" y2="24" gradientUnits="userSpaceOnUse">
+<stop stop-color="#8F8F8F"/>
+<stop offset="1" stop-color="#6D6D6D"/>
+</linearGradient>
+<linearGradient id="paint1_linear_16529_391320" x1="12" y1="0" x2="12" y2="24" gradientUnits="userSpaceOnUse">
+<stop stop-color="#F7931A"/>
+<stop offset="1" stop-color="#F67300"/>
+</linearGradient>
+<linearGradient id="paint2_linear_16529_391320" x1="11.8711" y1="3.3584" x2="11.8711" y2="19.3583" gradientUnits="userSpaceOnUse">
+<stop stop-color="white"/>
+<stop offset="1" stop-color="#A4B8FF"/>
+</linearGradient>
+<linearGradient id="paint3_linear_16529_391320" x1="11.8711" y1="3.3584" x2="11.8711" y2="19.3583" gradientUnits="userSpaceOnUse">
+<stop stop-color="white"/>
+<stop offset="1" stop-color="#A4CEFF"/>
+</linearGradient>
+<linearGradient id="paint4_linear_16529_391320" x1="11.8711" y1="3.3584" x2="11.8711" y2="19.3583" gradientUnits="userSpaceOnUse">
+<stop stop-color="#5F330B"/>
+<stop offset="1" stop-color="#462100"/>
+</linearGradient>
+<clipPath id="clip0_16529_391320">
+<rect width="24" height="24" fill="white"/>
+</clipPath>
+</defs>
</svg>
diff --git a/res/pictures/settings_row_icons/security.svg b/res/pictures/settings_row_icons/security.svg
index 994f17f2..6663c091 100644
--- a/res/pictures/settings_row_icons/security.svg
+++ b/res/pictures/settings_row_icons/security.svg
@@ -1,47 +1,42 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
- <g clip-path="url(#clip0_16845_60955)">
- <g clip-path="url(#clip1_16845_60955)">
- <path d="M0 8C0 5.19974 0 3.79961 0.544967 2.73005C1.02433 1.78924 1.78924 1.02433 2.73005 0.544967C3.79961 0 5.19974 0 8 0H16C18.8003 0 20.2004 0 21.27 0.544967C22.2108 1.02433 22.9757 1.78924 23.455 2.73005C24 3.79961 24 5.19974 24 8V16C24 18.8003 24 20.2004 23.455 21.27C22.9757 22.2108 22.2108 22.9757 21.27 23.455C20.2004 24 18.8003 24 16 24H8C5.19974 24 3.79961 24 2.73005 23.455C1.78924 22.9757 1.02433 22.2108 0.544967 21.27C0 20.2004 0 18.8003 0 16V8Z" fill="black"/>
- <path d="M0 8C0 5.19974 0 3.79961 0.544967 2.73005C1.02433 1.78924 1.78924 1.02433 2.73005 0.544967C3.79961 0 5.19974 0 8 0H16C18.8003 0 20.2004 0 21.27 0.544967C22.2108 1.02433 22.9757 1.78924 23.455 2.73005C24 3.79961 24 5.19974 24 8V16C24 18.8003 24 20.2004 23.455 21.27C22.9757 22.2108 22.2108 22.9757 21.27 23.455C20.2004 24 18.8003 24 16 24H8C5.19974 24 3.79961 24 2.73005 23.455C1.78924 22.9757 1.02433 22.2108 0.544967 21.27C0 20.2004 0 18.8003 0 16V8Z" fill="url(#paint0_linear_16845_60955)"/>
- <path d="M0 8C0 5.19974 0 3.79961 0.544967 2.73005C1.02433 1.78924 1.78924 1.02433 2.73005 0.544967C3.79961 0 5.19974 0 8 0H16C18.8003 0 20.2004 0 21.27 0.544967C22.2108 1.02433 22.9757 1.78924 23.455 2.73005C24 3.79961 24 5.19974 24 8V16C24 18.8003 24 20.2004 23.455 21.27C22.9757 22.2108 22.2108 22.9757 21.27 23.455C20.2004 24 18.8003 24 16 24H8C5.19974 24 3.79961 24 2.73005 23.455C1.78924 22.9757 1.02433 22.2108 0.544967 21.27C0 20.2004 0 18.8003 0 16V8Z" fill="url(#paint1_linear_16845_60955)"/>
- <path d="M0 8C0 5.19974 0 3.79961 0.544967 2.73005C1.02433 1.78924 1.78924 1.02433 2.73005 0.544967C3.79961 0 5.19974 0 8 0H16C18.8003 0 20.2004 0 21.27 0.544967C22.2108 1.02433 22.9757 1.78924 23.455 2.73005C24 3.79961 24 5.19974 24 8V16C24 18.8003 24 20.2004 23.455 21.27C22.9757 22.2108 22.2108 22.9757 21.27 23.455C20.2004 24 18.8003 24 16 24H8C5.19974 24 3.79961 24 2.73005 23.455C1.78924 22.9757 1.02433 22.2108 0.544967 21.27C0 20.2004 0 18.8003 0 16V8Z" fill="url(#paint2_linear_16845_60955)"/>
- <path d="M0 8C0 5.19974 0 3.79961 0.544967 2.73005C1.02433 1.78924 1.78924 1.02433 2.73005 0.544967C3.79961 0 5.19974 0 8 0H16C18.8003 0 20.2004 0 21.27 0.544967C22.2108 1.02433 22.9757 1.78924 23.455 2.73005C24 3.79961 24 5.19974 24 8V16C24 18.8003 24 20.2004 23.455 21.27C22.9757 22.2108 22.2108 22.9757 21.27 23.455C20.2004 24 18.8003 24 16 24H8C5.19974 24 3.79961 24 2.73005 23.455C1.78924 22.9757 1.02433 22.2108 0.544967 21.27C0 20.2004 0 18.8003 0 16V8Z" fill="#2C5CF6"/>
- <path d="M0 8C0 5.19974 0 3.79961 0.544967 2.73005C1.02433 1.78924 1.78924 1.02433 2.73005 0.544967C3.79961 0 5.19974 0 8 0H16C18.8003 0 20.2004 0 21.27 0.544967C22.2108 1.02433 22.9757 1.78924 23.455 2.73005C24 3.79961 24 5.19974 24 8V16C24 18.8003 24 20.2004 23.455 21.27C22.9757 22.2108 22.2108 22.9757 21.27 23.455C20.2004 24 18.8003 24 16 24H8C5.19974 24 3.79961 24 2.73005 23.455C1.78924 22.9757 1.02433 22.2108 0.544967 21.27C0 20.2004 0 18.8003 0 16V8Z" fill="url(#paint3_linear_16845_60955)"/>
- <path d="M0 8C0 5.19974 0 3.79961 0.544967 2.73005C1.02433 1.78924 1.78924 1.02433 2.73005 0.544967C3.79961 0 5.19974 0 8 0H16C18.8003 0 20.2004 0 21.27 0.544967C22.2108 1.02433 22.9757 1.78924 23.455 2.73005C24 3.79961 24 5.19974 24 8V16C24 18.8003 24 20.2004 23.455 21.27C22.9757 22.2108 22.2108 22.9757 21.27 23.455C20.2004 24 18.8003 24 16 24H8C5.19974 24 3.79961 24 2.73005 23.455C1.78924 22.9757 1.02433 22.2108 0.544967 21.27C0 20.2004 0 18.8003 0 16V8Z" fill="url(#paint4_linear_16845_60955)"/>
- <path d="M12 20.8489C9.98136 20.2984 8.31007 19.1102 6.98613 17.2843C5.66204 15.4584 5 13.417 5 11.1602V5.79006L12 3.16949L19 5.79006V11.1602C19 13.417 18.338 15.4584 17.0139 17.2843C15.6899 19.1102 14.0186 20.2984 12 20.8489ZM12 19.3736C13.5089 18.9069 14.7689 17.9852 15.78 16.6086C16.7911 15.2319 17.3822 13.6958 17.5533 12.0002H12V4.6591L6.4 6.75023V11.5714C6.4 11.6862 6.41556 11.8291 6.44667 12.0002H12V19.3736Z" fill="#E3E3E3"/>
- <path d="M12 20.8489C9.98136 20.2984 8.31007 19.1102 6.98613 17.2843C5.66204 15.4584 5 13.417 5 11.1602V5.79006L12 3.16949L19 5.79006V11.1602C19 13.417 18.338 15.4584 17.0139 17.2843C15.6899 19.1102 14.0186 20.2984 12 20.8489ZM12 19.3736C13.5089 18.9069 14.7689 17.9852 15.78 16.6086C16.7911 15.2319 17.3822 13.6958 17.5533 12.0002H12V4.6591L6.4 6.75023V11.5714C6.4 11.6862 6.41556 11.8291 6.44667 12.0002H12V19.3736Z" fill="url(#paint5_linear_16845_60955)"/>
- </g>
- </g>
- <defs>
- <linearGradient id="paint0_linear_16845_60955" x1="12" y1="0" x2="12" y2="24" gradientUnits="userSpaceOnUse">
- <stop stop-color="#2C2C2C"/>
- <stop offset="1" stop-color="#191919"/>
- </linearGradient>
- <linearGradient id="paint1_linear_16845_60955" x1="12" y1="0" x2="12" y2="24" gradientUnits="userSpaceOnUse">
- <stop stop-color="#351C83"/>
- <stop offset="1" stop-color="#0C0033"/>
- </linearGradient>
- <linearGradient id="paint2_linear_16845_60955" x1="12" y1="0" x2="12" y2="24" gradientUnits="userSpaceOnUse">
- <stop stop-color="#FF6200"/>
- <stop offset="1" stop-color="#E20F0F"/>
- </linearGradient>
- <linearGradient id="paint3_linear_16845_60955" x1="12" y1="0" x2="12" y2="24" gradientUnits="userSpaceOnUse">
- <stop stop-color="#2C5CF6"/>
- <stop offset="1" stop-color="#0F37FF"/>
- </linearGradient>
- <linearGradient id="paint4_linear_16845_60955" x1="12" y1="0" x2="12" y2="24" gradientUnits="userSpaceOnUse">
- <stop stop-color="#3B96FF"/>
- <stop offset="1" stop-color="#0044F0"/>
- </linearGradient>
- <linearGradient id="paint5_linear_16845_60955" x1="12" y1="3.16949" x2="12" y2="20.8489" gradientUnits="userSpaceOnUse">
- <stop stop-color="white"/>
- <stop offset="1" stop-color="#A4CEFF"/>
- </linearGradient>
- <clipPath id="clip0_16845_60955">
- <rect width="24" height="24" fill="white"/>
- </clipPath>
- <clipPath id="clip1_16845_60955">
- <rect width="24" height="24" fill="white"/>
- </clipPath>
- </defs>
+<g clip-path="url(#clip0_16529_391334)">
+<path d="M0 8C0 5.19974 0 3.79961 0.544967 2.73005C1.02433 1.78924 1.78924 1.02433 2.73005 0.544967C3.79961 0 5.19974 0 8 0H16C18.8003 0 20.2004 0 21.27 0.544967C22.2108 1.02433 22.9757 1.78924 23.455 2.73005C24 3.79961 24 5.19974 24 8V16C24 18.8003 24 20.2004 23.455 21.27C22.9757 22.2108 22.2108 22.9757 21.27 23.455C20.2004 24 18.8003 24 16 24H8C5.19974 24 3.79961 24 2.73005 23.455C1.78924 22.9757 1.02433 22.2108 0.544967 21.27C0 20.2004 0 18.8003 0 16V8Z" fill="black"/>
+<path d="M0 8C0 5.19974 0 3.79961 0.544967 2.73005C1.02433 1.78924 1.78924 1.02433 2.73005 0.544967C3.79961 0 5.19974 0 8 0H16C18.8003 0 20.2004 0 21.27 0.544967C22.2108 1.02433 22.9757 1.78924 23.455 2.73005C24 3.79961 24 5.19974 24 8V16C24 18.8003 24 20.2004 23.455 21.27C22.9757 22.2108 22.2108 22.9757 21.27 23.455C20.2004 24 18.8003 24 16 24H8C5.19974 24 3.79961 24 2.73005 23.455C1.78924 22.9757 1.02433 22.2108 0.544967 21.27C0 20.2004 0 18.8003 0 16V8Z" fill="url(#paint0_linear_16529_391334)"/>
+<path d="M0 8C0 5.19974 0 3.79961 0.544967 2.73005C1.02433 1.78924 1.78924 1.02433 2.73005 0.544967C3.79961 0 5.19974 0 8 0H16C18.8003 0 20.2004 0 21.27 0.544967C22.2108 1.02433 22.9757 1.78924 23.455 2.73005C24 3.79961 24 5.19974 24 8V16C24 18.8003 24 20.2004 23.455 21.27C22.9757 22.2108 22.2108 22.9757 21.27 23.455C20.2004 24 18.8003 24 16 24H8C5.19974 24 3.79961 24 2.73005 23.455C1.78924 22.9757 1.02433 22.2108 0.544967 21.27C0 20.2004 0 18.8003 0 16V8Z" fill="url(#paint1_linear_16529_391334)"/>
+<path d="M0 8C0 5.19974 0 3.79961 0.544967 2.73005C1.02433 1.78924 1.78924 1.02433 2.73005 0.544967C3.79961 0 5.19974 0 8 0H16C18.8003 0 20.2004 0 21.27 0.544967C22.2108 1.02433 22.9757 1.78924 23.455 2.73005C24 3.79961 24 5.19974 24 8V16C24 18.8003 24 20.2004 23.455 21.27C22.9757 22.2108 22.2108 22.9757 21.27 23.455C20.2004 24 18.8003 24 16 24H8C5.19974 24 3.79961 24 2.73005 23.455C1.78924 22.9757 1.02433 22.2108 0.544967 21.27C0 20.2004 0 18.8003 0 16V8Z" fill="url(#paint2_linear_16529_391334)"/>
+<path d="M0 8C0 5.19974 0 3.79961 0.544967 2.73005C1.02433 1.78924 1.78924 1.02433 2.73005 0.544967C3.79961 0 5.19974 0 8 0H16C18.8003 0 20.2004 0 21.27 0.544967C22.2108 1.02433 22.9757 1.78924 23.455 2.73005C24 3.79961 24 5.19974 24 8V16C24 18.8003 24 20.2004 23.455 21.27C22.9757 22.2108 22.2108 22.9757 21.27 23.455C20.2004 24 18.8003 24 16 24H8C5.19974 24 3.79961 24 2.73005 23.455C1.78924 22.9757 1.02433 22.2108 0.544967 21.27C0 20.2004 0 18.8003 0 16V8Z" fill="#2C5CF6"/>
+<path d="M0 8C0 5.19974 0 3.79961 0.544967 2.73005C1.02433 1.78924 1.78924 1.02433 2.73005 0.544967C3.79961 0 5.19974 0 8 0H16C18.8003 0 20.2004 0 21.27 0.544967C22.2108 1.02433 22.9757 1.78924 23.455 2.73005C24 3.79961 24 5.19974 24 8V16C24 18.8003 24 20.2004 23.455 21.27C22.9757 22.2108 22.2108 22.9757 21.27 23.455C20.2004 24 18.8003 24 16 24H8C5.19974 24 3.79961 24 2.73005 23.455C1.78924 22.9757 1.02433 22.2108 0.544967 21.27C0 20.2004 0 18.8003 0 16V8Z" fill="url(#paint3_linear_16529_391334)"/>
+<path d="M0 8C0 5.19974 0 3.79961 0.544967 2.73005C1.02433 1.78924 1.78924 1.02433 2.73005 0.544967C3.79961 0 5.19974 0 8 0H16C18.8003 0 20.2004 0 21.27 0.544967C22.2108 1.02433 22.9757 1.78924 23.455 2.73005C24 3.79961 24 5.19974 24 8V16C24 18.8003 24 20.2004 23.455 21.27C22.9757 22.2108 22.2108 22.9757 21.27 23.455C20.2004 24 18.8003 24 16 24H8C5.19974 24 3.79961 24 2.73005 23.455C1.78924 22.9757 1.02433 22.2108 0.544967 21.27C0 20.2004 0 18.8003 0 16V8Z" fill="url(#paint4_linear_16529_391334)"/>
+<path d="M12 20.8494C9.98136 20.2988 8.31007 19.1106 6.98613 17.2847C5.66204 15.4588 5 13.4175 5 11.1607V5.79049L12 3.16992L19 5.79049V11.1607C19 13.4175 18.338 15.4588 17.0139 17.2847C15.6899 19.1106 14.0186 20.2988 12 20.8494ZM12 19.374C13.5089 18.9073 14.7689 17.9857 15.78 16.609C16.7911 15.2323 17.3822 13.6962 17.5533 12.0007H12V4.65952L6.4 6.75066V11.5718C6.4 11.6866 6.41556 11.8295 6.44667 12.0007H12V19.374Z" fill="#E3E3E3"/>
+<path d="M12 20.8494C9.98136 20.2988 8.31007 19.1106 6.98613 17.2847C5.66204 15.4588 5 13.4175 5 11.1607V5.79049L12 3.16992L19 5.79049V11.1607C19 13.4175 18.338 15.4588 17.0139 17.2847C15.6899 19.1106 14.0186 20.2988 12 20.8494ZM12 19.374C13.5089 18.9073 14.7689 17.9857 15.78 16.609C16.7911 15.2323 17.3822 13.6962 17.5533 12.0007H12V4.65952L6.4 6.75066V11.5718C6.4 11.6866 6.41556 11.8295 6.44667 12.0007H12V19.374Z" fill="url(#paint5_linear_16529_391334)"/>
+</g>
+<defs>
+<linearGradient id="paint0_linear_16529_391334" x1="12" y1="0" x2="12" y2="24" gradientUnits="userSpaceOnUse">
+<stop stop-color="#2C2C2C"/>
+<stop offset="1" stop-color="#191919"/>
+</linearGradient>
+<linearGradient id="paint1_linear_16529_391334" x1="12" y1="0" x2="12" y2="24" gradientUnits="userSpaceOnUse">
+<stop stop-color="#351C83"/>
+<stop offset="1" stop-color="#0C0033"/>
+</linearGradient>
+<linearGradient id="paint2_linear_16529_391334" x1="12" y1="0" x2="12" y2="24" gradientUnits="userSpaceOnUse">
+<stop stop-color="#FF6200"/>
+<stop offset="1" stop-color="#E20F0F"/>
+</linearGradient>
+<linearGradient id="paint3_linear_16529_391334" x1="12" y1="0" x2="12" y2="24" gradientUnits="userSpaceOnUse">
+<stop stop-color="#2C5CF6"/>
+<stop offset="1" stop-color="#0F37FF"/>
+</linearGradient>
+<linearGradient id="paint4_linear_16529_391334" x1="12" y1="0" x2="12" y2="24" gradientUnits="userSpaceOnUse">
+<stop stop-color="#3B96FF"/>
+<stop offset="1" stop-color="#0044F0"/>
+</linearGradient>
+<linearGradient id="paint5_linear_16529_391334" x1="12" y1="3.16992" x2="12" y2="20.8494" gradientUnits="userSpaceOnUse">
+<stop stop-color="white"/>
+<stop offset="1" stop-color="#A4CEFF"/>
+</linearGradient>
+<clipPath id="clip0_16529_391334">
+<rect width="24" height="24" fill="white"/>
+</clipPath>
+</defs>
</svg>
diff --git a/res/pictures/settings_row_icons/wc.svg b/res/pictures/settings_row_icons/wc.svg
new file mode 100644
index 00000000..5f334128
--- /dev/null
+++ b/res/pictures/settings_row_icons/wc.svg
@@ -0,0 +1,29 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_17329_949648)">
+<path d="M0 8C0 5.19974 0 3.79961 0.544967 2.73005C1.02433 1.78924 1.78924 1.02433 2.73005 0.544967C3.79961 0 5.19974 0 8 0H16C18.8003 0 20.2004 0 21.27 0.544967C22.2108 1.02433 22.9757 1.78924 23.455 2.73005C24 3.79961 24 5.19974 24 8V16C24 18.8003 24 20.2004 23.455 21.27C22.9757 22.2108 22.2108 22.9757 21.27 23.455C20.2004 24 18.8003 24 16 24H8C5.19974 24 3.79961 24 2.73005 23.455C1.78924 22.9757 1.02433 22.2108 0.544967 21.27C0 20.2004 0 18.8003 0 16V8Z" fill="url(#paint0_linear_17329_949648)"/>
+<path d="M0 8C0 5.19974 0 3.79961 0.544967 2.73005C1.02433 1.78924 1.78924 1.02433 2.73005 0.544967C3.79961 0 5.19974 0 8 0H16C18.8003 0 20.2004 0 21.27 0.544967C22.2108 1.02433 22.9757 1.78924 23.455 2.73005C24 3.79961 24 5.19974 24 8V16C24 18.8003 24 20.2004 23.455 21.27C22.9757 22.2108 22.2108 22.9757 21.27 23.455C20.2004 24 18.8003 24 16 24H8C5.19974 24 3.79961 24 2.73005 23.455C1.78924 22.9757 1.02433 22.2108 0.544967 21.27C0 20.2004 0 18.8003 0 16V8Z" fill="url(#paint1_linear_17329_949648)"/>
+<path d="M0 8C0 5.19974 0 3.79961 0.544967 2.73005C1.02433 1.78924 1.78924 1.02433 2.73005 0.544967C3.79961 0 5.19974 0 8 0H16C18.8003 0 20.2004 0 21.27 0.544967C22.2108 1.02433 22.9757 1.78924 23.455 2.73005C24 3.79961 24 5.19974 24 8V16C24 18.8003 24 20.2004 23.455 21.27C22.9757 22.2108 22.2108 22.9757 21.27 23.455C20.2004 24 18.8003 24 16 24H8C5.19974 24 3.79961 24 2.73005 23.455C1.78924 22.9757 1.02433 22.2108 0.544967 21.27C0 20.2004 0 18.8003 0 16V8Z" fill="url(#paint2_linear_17329_949648)"/>
+<path d="M21.6004 12.2103L15.9535 17.8165L12.0004 13.8926L8.04727 17.8165L2.40039 12.2103L4.0931 10.5301L8.04727 14.454L12.0004 10.5301L15.9535 14.454L19.9077 10.5301L21.6004 12.2103ZM5.78997 8.85195C9.62131 5.04933 14.3815 5.04937 18.2129 8.85195L16.5181 10.5332C13.6046 7.64263 10.3981 7.64269 7.48477 10.5342L5.78997 8.85195Z" fill="url(#paint3_linear_17329_949648)"/>
+</g>
+<defs>
+<linearGradient id="paint0_linear_17329_949648" x1="12" y1="0" x2="12" y2="24" gradientUnits="userSpaceOnUse">
+<stop stop-color="#0082F8"/>
+<stop offset="1" stop-color="#0666FF"/>
+</linearGradient>
+<linearGradient id="paint1_linear_17329_949648" x1="12" y1="0" x2="12" y2="24" gradientUnits="userSpaceOnUse">
+<stop stop-color="#2B9AFF"/>
+<stop offset="1" stop-color="#0666FF"/>
+</linearGradient>
+<linearGradient id="paint2_linear_17329_949648" x1="12" y1="0" x2="12" y2="24" gradientUnits="userSpaceOnUse">
+<stop stop-color="#3396FF"/>
+<stop offset="1" stop-color="#007CFF"/>
+</linearGradient>
+<linearGradient id="paint3_linear_17329_949648" x1="12.0004" y1="6" x2="12.0004" y2="17.8165" gradientUnits="userSpaceOnUse">
+<stop stop-color="white"/>
+<stop offset="1" stop-color="#BFDEFF"/>
+</linearGradient>
+<clipPath id="clip0_17329_949648">
+<rect width="24" height="24" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb
index 204e12ee..ab480a48 100644
--- a/res/values/strings_ar.arb
+++ b/res/values/strings_ar.arb
@@ -242,6 +242,7 @@
"connected": "متصل",
"connection_sync": "الاتصال والمزامنة",
"connections": "الاتصالات",
+ "connections_desc": "إدارة الاتصالات بالخدمات وواجهات برمجة التطبيقات التابعة لجهات خارجية.",
"connectWalletPrompt": "قم بتوصيل محفظتك عبر WalletConnect لإجراء المعاملات",
"contact": "جهة اتصال",
"contact_list_contacts": "جهات الاتصال",
@@ -756,6 +757,7 @@
"privacy": "الخصوصية",
"privacy_and_security": "الخصوصية والأمان",
"privacy_and_security_desc": "قم بتكوين إعدادات المصادقة والأمان وإعداد المصادقة الثنائية (2FA) في Cake.",
+ "privacy_desc": "تغيير إعدادات الخصوصية وتبديل ميزات الخصوصية الخاصة.",
"privacy_features": "ميزات الخصوصية",
"privacy_policy": "سياسة الخصوصية",
"privacy_settings": "إعدادات الخصوصية",
diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb
index 84524d0e..d50474f4 100644
--- a/res/values/strings_bg.arb
+++ b/res/values/strings_bg.arb
@@ -242,6 +242,7 @@
"connected": "Свързан",
"connection_sync": "Връзка и синхронизация",
"connections": "Връзки",
+ "connections_desc": "Управлявайте връзки към услуги и API на трети страни.",
"connectWalletPrompt": "Свържете портфейла си с WalletConnect, за да извършвате транзакции",
"contact": "Контакт",
"contact_list_contacts": "Контакти",
@@ -756,6 +757,7 @@
"privacy": "Поверителност",
"privacy_and_security": "Поверителност и сигурност",
"privacy_and_security_desc": "Конфигурирайте настройките за удостоверяване и сигурност и настройте Cake 2FA.",
+ "privacy_desc": "Променете настройките за поверителност и превключете специални функции за поверителност.",
"privacy_features": "Функции за поверителност",
"privacy_policy": "Политика за поверителност",
"privacy_settings": "Настройки за поверителност",
diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb
index 4a62c699..aebca6a9 100644
--- a/res/values/strings_cs.arb
+++ b/res/values/strings_cs.arb
@@ -242,6 +242,7 @@
"connected": "Připojeno",
"connection_sync": "Připojení a synchronizace",
"connections": "Připojení",
+ "connections_desc": "Správa připojení ke službám a rozhraním API třetích stran.",
"connectWalletPrompt": "Připojte svou peněženku přes WalletConnect a provádějte transakce",
"contact": "Kontakt",
"contact_list_contacts": "Kontakty",
@@ -756,6 +757,7 @@
"privacy": "Soukromí",
"privacy_and_security": "Soukromí a zabezpečení",
"privacy_and_security_desc": "Nakonfigurujte nastavení ověřování a zabezpečení a nastavte Cake 2FA.",
+ "privacy_desc": "Změňte nastavení ochrany osobních údajů a přepínejte speciální funkce ochrany osobních údajů.",
"privacy_features": "Funkce soukromí",
"privacy_policy": "Zásady ochrany osobních údajů",
"privacy_settings": "Nastavení soukromí",
diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb
index 8183db3e..f3b37917 100644
--- a/res/values/strings_de.arb
+++ b/res/values/strings_de.arb
@@ -242,6 +242,7 @@
"connected": "Verbunden",
"connection_sync": "Verbindung und Synchronisierung",
"connections": "Verbindungen",
+ "connections_desc": "Verwalten Sie Verbindungen zu Diensten und APIs von Drittanbietern.",
"connectWalletPrompt": "Verbinden Sie Ihr Wallet mit WalletConnect, um Transaktionen durchzuführen",
"contact": "Kontakt",
"contact_list_contacts": "Kontakte",
@@ -757,6 +758,7 @@
"privacy": "Privatsphäre",
"privacy_and_security": "Datenschutz & Sicherheit",
"privacy_and_security_desc": "Konfigurieren Sie Authentifizierungs- und Sicherheitseinstellungen und richten Sie Cake 2FA ein.",
+ "privacy_desc": "Ändern Sie die Datenschutzeinstellungen und schalten Sie spezielle Datenschutzfunktionen ein.",
"privacy_features": "Datenschutzfunktionen",
"privacy_policy": "Datenschutzerklärung",
"privacy_settings": "Datenschutzeinstellungen",
diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb
index 1697827b..f55ddf0f 100644
--- a/res/values/strings_en.arb
+++ b/res/values/strings_en.arb
@@ -242,6 +242,7 @@
"connected": "Connected",
"connection_sync": "Connection and sync",
"connections": "Connections",
+ "connections_desc": "Manage connections to services and third party APIs.",
"connectWalletPrompt": "Connect your wallet with WalletConnect to make transactions",
"contact": "Contact",
"contact_list_contacts": "Contacts",
@@ -757,6 +758,7 @@
"privacy": "Privacy",
"privacy_and_security": "Privacy & Security",
"privacy_and_security_desc": "Configure authentication and security settings and setup Cake 2FA.",
+ "privacy_desc": "Change privacy settings and toggle special privacy features.",
"privacy_features": "Privacy features",
"privacy_policy": "Privacy Policy",
"privacy_settings": "Privacy settings",
diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb
index 0ba2235a..49ce3fc0 100644
--- a/res/values/strings_es.arb
+++ b/res/values/strings_es.arb
@@ -242,6 +242,7 @@
"connected": "Conectado",
"connection_sync": "Conexión y sincronización",
"connections": "Conexiones",
+ "connections_desc": "Administrar conexiones a servicios y API de terceros.",
"connectWalletPrompt": "Conecta tu billetera con WalletConnect para realizar transacciones",
"contact": "Contacto",
"contact_list_contacts": "Contactos",
@@ -757,6 +758,7 @@
"privacy": "Privacidad",
"privacy_and_security": "Privacidad y seguridad",
"privacy_and_security_desc": "Configure los ajustes de autenticación y seguridad y configure Cake 2FA.",
+ "privacy_desc": "Cambie la configuración de privacidad y alterne funciones de privacidad especiales.",
"privacy_features": "Funciones de privacidad",
"privacy_policy": "Política de privacidad",
"privacy_settings": "Configuración de privacidad",
diff --git a/res/values/strings_fa.arb b/res/values/strings_fa.arb
index cad8e117..5e1edfa7 100644
--- a/res/values/strings_fa.arb
+++ b/res/values/strings_fa.arb
@@ -240,6 +240,7 @@
"connected": "متصل",
"connection_sync": "اتصال و همگامسازی",
"connections": "اتصالات",
+ "connections_desc": "اتصالات به سرویس ها و API های شخص ثالث را مدیریت کنید.",
"connectWalletPrompt": "برای انجام تراکنشها، کیف پول خود را از طریق WalletConnect متصل کنید",
"contact": "مخاطب",
"contact_list_contacts": "مخاطبین",
@@ -755,6 +756,7 @@
"privacy": "حریم خصوصی",
"privacy_and_security": "حریم خصوصی و امنیت",
"privacy_and_security_desc": "تنظیمات احراز هویت و امنیت را پیکربندی کنید و Cake 2FA را راهاندازی کنید.",
+ "privacy_desc": "تنظیمات حریم خصوصی را تغییر دهید و ویژگی های حریم خصوصی را تغییر دهید.",
"privacy_features": "ویژگیهای حریم خصوصی",
"privacy_policy": "سیاست حفظ حریم خصوصی",
"privacy_settings": "تنظیمات حریم خصوصی",
diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb
index fc21a4dd..625bbde3 100644
--- a/res/values/strings_fr.arb
+++ b/res/values/strings_fr.arb
@@ -242,6 +242,7 @@
"connected": "Connecté",
"connection_sync": "Connexion et synchronisation",
"connections": "Connexions",
+ "connections_desc": "Gérez les connexions aux services et aux API tierces.",
"connectWalletPrompt": "Connectez votre portefeuille avec WalletConnect pour effectuer des transactions",
"contact": "Contact",
"contact_list_contacts": "Contacts",
@@ -756,6 +757,7 @@
"privacy": "Confidentialité",
"privacy_and_security": "Confidentialité et sécurité",
"privacy_and_security_desc": "Configurez les paramètres d'authentification et de sécurité, et configurez Cake 2FA.",
+ "privacy_desc": "Modifiez les paramètres de confidentialité et activez les fonctionnalités de confidentialité spéciales.",
"privacy_features": "Fonctionnalités de confidentialité",
"privacy_policy": "Politique de confidentialité",
"privacy_settings": "Paramètres de confidentialité",
diff --git a/res/values/strings_gn.arb b/res/values/strings_gn.arb
index 1e03da9d..7c535a74 100644
--- a/res/values/strings_gn.arb
+++ b/res/values/strings_gn.arb
@@ -192,6 +192,7 @@
"connect_your_hardware_wallet_ios": "Embojoaju nde billetera hardware Bluetooth ndive",
"connection_sync": "Joaju ha ñembojuehe",
"connections": "Jeikeha",
+ "connections_desc": "Emohenda joaju umi servicio ha API mbohapýha rehegua.",
"connectWalletPrompt": "Embojoaju nde billetera WalletConnect ndive hag̃ua rejapo transacción",
"contact": "Contacto",
"contact_list_contacts": "Ñe'ẽngára",
@@ -589,6 +590,7 @@
"privacy": "Ñemigua",
"privacy_and_security": "Privasida ha Tekorosã",
"privacy_and_security_desc": "Emohenda ñemboheko hag̃ua jehechajey hag̃ua hag̃ua hag̃ua hag̃ua seguridad ha emboheko Cake 2FA.",
+ "privacy_desc": "Emoambue ñemigua ñemboheko ha embohasa ñemigua mba’ekuaarã especial.",
"privacy_features": "Tembiapoite ñemigua",
"privacy_policy": "Purureko ñemi rehegua",
"privacy_settings": "Ñemohenda ñemigua",
diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb
index 7ace3415..4d57e1b1 100644
--- a/res/values/strings_ha.arb
+++ b/res/values/strings_ha.arb
@@ -242,6 +242,7 @@
"connected": "An haɗa",
"connection_sync": "Haɗi da aiki tare",
"connections": "Haɗe-haɗe",
+ "connections_desc": "Sarrafa haɗin kai zuwa ayyuka da APIs na ɓangare na uku.",
"connectWalletPrompt": "Haɗa walat ɗinka da WalletConnect don yin ma'amaloli",
"contact": "Tuntuɓa",
"contact_list_contacts": "Lambobin sadarwa",
@@ -758,6 +759,7 @@
"privacy": "Sirri",
"privacy_and_security": "Sirri & Tsaro",
"privacy_and_security_desc": "Saita tabbatarwa da saitunan tsaro, sannan ka saita Cake 2FA.",
+ "privacy_desc": "Canja saitunan keɓantawa kuma kunna fasalolin keɓantawa na musamman.",
"privacy_features": "Siffofin keɓantawa",
"privacy_policy": "Manufar Sirri",
"privacy_settings": "Saitunan keɓantawa",
diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb
index 71aab4da..dc779052 100644
--- a/res/values/strings_hi.arb
+++ b/res/values/strings_hi.arb
@@ -242,6 +242,7 @@
"connected": "कनेक्टेड",
"connection_sync": "कनेक्शन और सिंक",
"connections": "कनेक्शन",
+ "connections_desc": "सेवाओं और तृतीय पक्ष एपीआई से कनेक्शन प्रबंधित करें।",
"connectWalletPrompt": "लेन-देन करने के लिए अपने वॉलेट को WalletConnect से कनेक्ट करें",
"contact": "संपर्क",
"contact_list_contacts": "संपर्क",
@@ -757,6 +758,7 @@
"privacy": "गोपनीयता",
"privacy_and_security": "निजता और सुरक्षा",
"privacy_and_security_desc": "प्रमाणीकरण और सुरक्षा सेटिंग्स कॉन्फ़िगर करें और Cake 2FA सेट अप करें।",
+ "privacy_desc": "गोपनीयता सेटिंग्स बदलें और विशेष गोपनीयता सुविधाओं को टॉगल करें।",
"privacy_features": "गोपनीयता सुविधाएँ",
"privacy_policy": "गोपनीयता नीति",
"privacy_settings": "गोपनीयता सेटिंग्स",
diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb
index d5854b3c..4ca1ae54 100644
--- a/res/values/strings_hr.arb
+++ b/res/values/strings_hr.arb
@@ -242,6 +242,7 @@
"connected": "Povezano",
"connection_sync": "Povezivanje i sinkronizacija",
"connections": "Veze",
+ "connections_desc": "Upravljajte vezama s uslugama i API-jima trećih strana.",
"connectWalletPrompt": "Povežite svoj novčanik s WalletConnectom za izvršavanje transakcija",
"contact": "Kontakt",
"contact_list_contacts": "Kontakti",
@@ -756,6 +757,7 @@
"privacy": "Privatnost",
"privacy_and_security": "Privatnost i sigurnost",
"privacy_and_security_desc": "Konfigurirajte postavke provjere autentičnosti i sigurnosti te postavite Cake 2FA.",
+ "privacy_desc": "Promijenite postavke privatnosti i uključite/isključite posebne značajke privatnosti.",
"privacy_features": "Značajke privatnosti",
"privacy_policy": "Pravila privatnosti",
"privacy_settings": "Postavke privatnosti",
diff --git a/res/values/strings_hy.arb b/res/values/strings_hy.arb
index 470fc166..f884ebdd 100644
--- a/res/values/strings_hy.arb
+++ b/res/values/strings_hy.arb
@@ -242,6 +242,7 @@
"connected": "Միացված",
"connection_sync": "Կապ և համաժամեցում",
"connections": "Միացումներ",
+ "connections_desc": "Կառավարեք կապերը ծառայությունների և երրորդ կողմի API-ների հետ:",
"connectWalletPrompt": "Միացրեք ձեր դրամապանակը WalletConnect-ի միջոցով՝ գործարքներ կատարելու համար",
"contact": "Կոնտակտ",
"contact_list_contacts": "Կոնտակտներ",
@@ -755,6 +756,7 @@
"privacy": "Գաղտնիություն",
"privacy_and_security": "Գաղտնիություն և անվտանգություն",
"privacy_and_security_desc": "Կազմաձևեք նույնականացման և անվտանգության կարգավորումները և կարգավորեք Cake 2FA-ն։",
+ "privacy_desc": "Փոխեք գաղտնիության կարգավորումները և միացրեք գաղտնիության հատուկ գործառույթները:",
"privacy_features": "Գաղտնիության գործառույթներ",
"privacy_policy": "Գաղտնիության քաղաքականություն",
"privacy_settings": "Գաղտնիության կարգավորումներ",
diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb
index d1bb7b41..99a58739 100644
--- a/res/values/strings_id.arb
+++ b/res/values/strings_id.arb
@@ -242,6 +242,7 @@
"connected": "Terhubung",
"connection_sync": "Koneksi dan sinkronisasi",
"connections": "Koneksi",
+ "connections_desc": "Kelola koneksi ke layanan dan API pihak ketiga.",
"connectWalletPrompt": "Hubungkan dompet Anda dengan WalletConnect untuk melakukan transaksi",
"contact": "Kontak",
"contact_list_contacts": "Kontak",
@@ -758,6 +759,7 @@
"privacy": "Privasi",
"privacy_and_security": "Privasi & Keamanan",
"privacy_and_security_desc": "Konfigurasikan pengaturan autentikasi dan keamanan serta siapkan Cake 2FA.",
+ "privacy_desc": "Ubah pengaturan privasi dan aktifkan fitur privasi khusus.",
"privacy_features": "Fitur privasi",
"privacy_policy": "Kebijakan Privasi",
"privacy_settings": "Pengaturan Privasi",
diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb
index bb97d1a3..72ed9288 100644
--- a/res/values/strings_it.arb
+++ b/res/values/strings_it.arb
@@ -242,6 +242,7 @@
"connected": "Connesso",
"connection_sync": "Connessione e sincronizzazione",
"connections": "Connessioni",
+ "connections_desc": "Gestisci le connessioni a servizi e API di terze parti.",
"connectWalletPrompt": "Collega il tuo wallet con WalletConnect per effettuare transazioni",
"contact": "Contatto",
"contact_list_contacts": "Contatti",
@@ -757,6 +758,7 @@
"privacy": "Privacy",
"privacy_and_security": "Privacy e sicurezza",
"privacy_and_security_desc": "Configura le impostazioni di autenticazione e sicurezza e imposta Cake 2FA.",
+ "privacy_desc": "Modifica le impostazioni sulla privacy e attiva le funzionalità speciali sulla privacy.",
"privacy_features": "Funzionalità per la privacy",
"privacy_policy": "Informativa sulla privacy",
"privacy_settings": "Impostazioni sulla privacy",
diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb
index 8f83c67a..1597fb30 100644
--- a/res/values/strings_ja.arb
+++ b/res/values/strings_ja.arb
@@ -242,6 +242,7 @@
"connected": "接続済み",
"connection_sync": "接続と同期",
"connections": "接続",
+ "connections_desc": "サービスおよびサードパーティ API への接続を管理します。",
"connectWalletPrompt": "WalletConnect でウォレットを接続して取引を行う",
"contact": "連絡先",
"contact_list_contacts": "連絡先",
@@ -757,6 +758,7 @@
"privacy": "プライバシー",
"privacy_and_security": "プライバシーとセキュリティ",
"privacy_and_security_desc": "認証とセキュリティの設定を構成し、Cake 2FA をセットアップします。",
+ "privacy_desc": "プライバシー設定を変更し、特別なプライバシー機能を切り替えます。",
"privacy_features": "プライバシー機能",
"privacy_policy": "プライバシーポリシー",
"privacy_settings": "プライバシー設定",
diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb
index 8fa44e7e..6df7fd1b 100644
--- a/res/values/strings_ko.arb
+++ b/res/values/strings_ko.arb
@@ -242,6 +242,7 @@
"connected": "연결됨",
"connection_sync": "연결 및 동기화",
"connections": "연결",
+ "connections_desc": "서비스 및 타사 API에 대한 연결을 관리합니다.",
"connectWalletPrompt": "거래를 하려면 WalletConnect로 지갑을 연결하세요",
"contact": "연락처",
"contact_list_contacts": "연락처",
@@ -757,6 +758,7 @@
"privacy": "개인정보 보호",
"privacy_and_security": "개인정보 보호 및 보안",
"privacy_and_security_desc": "인증 및 보안 설정을 구성하고 Cake 2FA를 설정합니다.",
+ "privacy_desc": "개인정보 보호 설정을 변경하고 특별 개인정보 보호 기능을 전환하세요.",
"privacy_features": "개인정보 보호 기능",
"privacy_policy": "개인정보처리방침",
"privacy_settings": "개인정보 보호 설정",
diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb
index d75350cc..a9785f5b 100644
--- a/res/values/strings_my.arb
+++ b/res/values/strings_my.arb
@@ -242,6 +242,7 @@
"connected": "ချိတ်ဆက်ပြီး",
"connection_sync": "ချိတ်ဆက်မှုနှင့် ထပ်တူညီစေခြင်း",
"connections": "ချိတ်ဆက်မှုများ",
+ "connections_desc": "ဝန်ဆောင်မှုများနှင့် ပြင်ပကုမ္ပဏီ API များသို့ ချိတ်ဆက်မှုများကို စီမံပါ။",
"connectWalletPrompt": "ငွေလွှဲပြောင်းမှုများ ပြုလုပ်ရန် WalletConnect ဖြင့် သင့်ပိုက်ဆံအိတ်ကို ချိတ်ဆက်ပါ",
"contact": "ဆက်သွယ်ရန်",
"contact_list_contacts": "အဆက်အသွယ်များ",
@@ -756,6 +757,7 @@
"privacy": "ကိုယ်ရေးလုံခြုံမှု",
"privacy_and_security": "ကိုယ်ရေးကိုယ်တာနှင့် လုံခြုံရေး",
"privacy_and_security_desc": "အထောက်အထားစိစစ်ခြင်းနှင့် လုံခြုံရေးဆက်တင်များကို ပြင်ဆင်သတ်မှတ်ပြီး Cake 2FA ကို စနစ်ထည့်သွင်းပါ။",
+ "privacy_desc": "ကိုယ်ရေးကိုယ်တာဆက်တင်များကိုပြောင်းလဲပြီး အထူးကိုယ်ရေးကိုယ်တာအင်္ဂါရပ်များကို ပြောင်းပါ။",
"privacy_features": "ကိုယ်ရေးလုံခြုံရေး အင်္ဂါရပ်များ",
"privacy_policy": "ကိုယ်ရေးအချက်အလက်မူဝါဒ",
"privacy_settings": "ကိုယ်ရေးကိုယ်တာ ဆက်တင်များ",
diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb
index d4d7348c..3d85f18f 100644
--- a/res/values/strings_nl.arb
+++ b/res/values/strings_nl.arb
@@ -240,6 +240,7 @@
"connected": "Verbonden",
"connection_sync": "Verbinding en synchronisatie",
"connections": "Verbindingen",
+ "connections_desc": "Beheer verbindingen met services en API's van derden.",
"connectWalletPrompt": "Verbind je wallet met WalletConnect om transacties uit te voeren",
"contact": "Contact",
"contact_list_contacts": "Contacten",
@@ -753,6 +754,7 @@
"privacy": "Privacy",
"privacy_and_security": "Privacy en beveiliging",
"privacy_and_security_desc": "Configureer de authenticatie- en beveiligingsinstellingen en stel Cake 2FA in.",
+ "privacy_desc": "Wijzig privacy-instellingen en schakel speciale privacyfuncties in.",
"privacy_features": "Privacyfuncties",
"privacy_policy": "Privacybeleid",
"privacy_settings": "Privacy-instellingen",
diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb
index 8238356e..e80a7d3b 100644
--- a/res/values/strings_pl.arb
+++ b/res/values/strings_pl.arb
@@ -242,6 +242,7 @@
"connected": "Połączono",
"connection_sync": "Połączenie i synchronizacja",
"connections": "Połączenia",
+ "connections_desc": "Zarządzaj połączeniami z usługami i interfejsami API stron trzecich.",
"connectWalletPrompt": "Połącz swój portfel z WalletConnect, aby wykonywać transakcje",
"contact": "Kontakt",
"contact_list_contacts": "Kontakty",
@@ -755,6 +756,7 @@
"privacy": "Prywatność",
"privacy_and_security": "Prywatność i bezpieczeństwo",
"privacy_and_security_desc": "Skonfiguruj ustawienia uwierzytelniania i zabezpieczeń oraz skonfiguruj Cake 2FA.",
+ "privacy_desc": "Zmień ustawienia prywatności i przełącz specjalne funkcje prywatności.",
"privacy_features": "Funkcje prywatności",
"privacy_policy": "Polityka prywatności",
"privacy_settings": "Ustawienia prywatności",
diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb
index b807bbc7..d2823434 100644
--- a/res/values/strings_pt.arb
+++ b/res/values/strings_pt.arb
@@ -242,6 +242,7 @@
"connected": "Conectado",
"connection_sync": "Conexão e sincronização",
"connections": "Conexões",
+ "connections_desc": "Gerencie conexões com serviços e APIs de terceiros.",
"connectWalletPrompt": "Conecte sua carteira ao WalletConnect para realizar transações",
"contact": "Contato",
"contact_list_contacts": "Contatos",
@@ -758,6 +759,7 @@
"privacy": "Privacidade",
"privacy_and_security": "Privacidade e Segurança",
"privacy_and_security_desc": "Configure as definições de autenticação e segurança e configure o Cake 2FA.",
+ "privacy_desc": "Altere as configurações de privacidade e ative recursos especiais de privacidade.",
"privacy_features": "Recursos de privacidade",
"privacy_policy": "Política de Privacidade",
"privacy_settings": "Configurações de privacidade",
diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb
index 9e888ab7..416377e8 100644
--- a/res/values/strings_ru.arb
+++ b/res/values/strings_ru.arb
@@ -242,6 +242,7 @@
"connected": "Подключено",
"connection_sync": "Подключение и синхронизация",
"connections": "Подключения",
+ "connections_desc": "Управляйте подключениями к сервисам и сторонним API.",
"connectWalletPrompt": "Подключите свой кошелек к WalletConnect, чтобы совершать транзакции",
"contact": "Контакт",
"contact_list_contacts": "Контакты",
@@ -757,6 +758,7 @@
"privacy": "Конфиденциальность",
"privacy_and_security": "Конфиденциальность и безопасность",
"privacy_and_security_desc": "Настройте параметры аутентификации и безопасности, а также настройте Cake 2FA.",
+ "privacy_desc": "Измените настройки конфиденциальности и включите специальные функции конфиденциальности.",
"privacy_features": "Функции конфиденциальности",
"privacy_policy": "Политика конфиденциальности",
"privacy_settings": "Настройки конфиденциальности",
diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb
index faae414b..fc986ff8 100644
--- a/res/values/strings_th.arb
+++ b/res/values/strings_th.arb
@@ -242,6 +242,7 @@
"connected": "เชื่อมต่อแล้ว",
"connection_sync": "การเชื่อมต่อและซิงค์",
"connections": "การเชื่อมต่อ",
+ "connections_desc": "จัดการการเชื่อมต่อกับบริการและ API ของบุคคลที่สาม",
"connectWalletPrompt": "เชื่อมต่อกระเป๋าเงินของคุณกับ WalletConnect เพื่อทำธุรกรรม",
"contact": "ผู้ติดต่อ",
"contact_list_contacts": "รายชื่อผู้ติดต่อ",
@@ -756,6 +757,7 @@
"privacy": "ความเป็นส่วนตัว",
"privacy_and_security": "ความเป็นส่วนตัวและความปลอดภัย",
"privacy_and_security_desc": "กำหนดค่าการยืนยันตัวตนและการตั้งค่าความปลอดภัย และตั้งค่า Cake 2FA",
+ "privacy_desc": "เปลี่ยนการตั้งค่าความเป็นส่วนตัวและสลับคุณสมบัติความเป็นส่วนตัวพิเศษ",
"privacy_features": "ฟีเจอร์ความเป็นส่วนตัว",
"privacy_policy": "นโยบายความเป็นส่วนตัว",
"privacy_settings": "การตั้งค่าความเป็นส่วนตัว",
diff --git a/res/values/strings_tl.arb b/res/values/strings_tl.arb
index ee61e64e..2893fdc4 100644
--- a/res/values/strings_tl.arb
+++ b/res/values/strings_tl.arb
@@ -242,6 +242,7 @@
"connected": "Nakakonekta",
"connection_sync": "Koneksyon at pag-sync",
"connections": "Mga koneksyon",
+ "connections_desc": "Pamahalaan ang mga koneksyon sa mga serbisyo at mga third party na API.",
"connectWalletPrompt": "Ikonekta ang iyong wallet sa WalletConnect para makapag-transact",
"contact": "Kontak",
"contact_list_contacts": "Mga Contact",
@@ -756,6 +757,7 @@
"privacy": "Pagkapribado",
"privacy_and_security": "Pagkapribado at Seguridad",
"privacy_and_security_desc": "I-configure ang mga setting ng pagpapatotoo at seguridad at i-set up ang Cake 2FA.",
+ "privacy_desc": "Baguhin ang mga setting ng privacy at i-toggle ang mga espesyal na feature sa privacy.",
"privacy_features": "Mga tampok sa privacy",
"privacy_policy": "Patakaran sa Privacy",
"privacy_settings": "Mga setting sa privacy",
diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb
index 5975b61d..f2753f94 100644
--- a/res/values/strings_tr.arb
+++ b/res/values/strings_tr.arb
@@ -242,6 +242,7 @@
"connected": "Bağlı",
"connection_sync": "Bağlantı ve senkronizasyon",
"connections": "Bağlantılar",
+ "connections_desc": "Hizmetlere ve üçüncü taraf API'lere olan bağlantıları yönetin.",
"connectWalletPrompt": "İşlem yapmak için cüzdanınızı WalletConnect ile bağlayın",
"contact": "Kişi",
"contact_list_contacts": "Kişiler",
@@ -756,6 +757,7 @@
"privacy": "Gizlilik",
"privacy_and_security": "Gizlilik ve Güvenlik",
"privacy_and_security_desc": "Kimlik doğrulama ve güvenlik ayarlarını yapılandırın ve Cake 2FA'yı ayarlayın.",
+ "privacy_desc": "Gizlilik ayarlarını değiştirin ve özel gizlilik özelliklerini değiştirin.",
"privacy_features": "Gizlilik özellikleri",
"privacy_policy": "Gizlilik Politikası",
"privacy_settings": "Gizlilik ayarları",
diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb
index 06dc6ff9..fc280695 100644
--- a/res/values/strings_uk.arb
+++ b/res/values/strings_uk.arb
@@ -242,6 +242,7 @@
"connected": "Підключено",
"connection_sync": "Підключення та синхронізація",
"connections": "Підключення"Why this scored 18/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.