mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-11-15 09:24:01 +01:00
* add Wallet Accounts page and integrate UI * account model refactor * add walletInfoAccount table and API * add WalletAccountList API * add multi-account support for Electrum wallets * add Bitcoin lightning card and card style handling * refine account filtering and card selection * update current account balance on wallet changes * update configure.dar * Use named parameters for card design * Add Bitcoin account handling and refactor lookup * refactor dashboard * refactor cards UI and account balance handling * Improve Bitcoin account selection and balances * restrict unspent coin usage to current account * filter transactions by current Bitcoin account * refactor electrum wallet * refactor address generation * add accountIndex to address fetch logic * Update configure.dart * reload transactions on Bitcoin account change * restore multiple BTC accounts and improve fetch * show account balance with in btc * track account index in Bitcoin transactions * discover btc BIP39 accounts during restore * fix account switching and card ordering bugs * fix card customizer * limit account name length in modal * update BTC account list balance display * auto-reformat * formating fix * skip HD map validation * fix 0 balance issue * minor fix * quick bitcoin wallet sync * restore shuffle change output * restore address lookup fix * Update electrum.dart * remove account customizer * Merge branch 'CW-1142-Add-accounts-feature-to-BTC' into CW-1551-Quick-Bitcoin-Wallet-Sync * probe only segwit in account discovery * add account discovery limit and tracking * Improve Electrum sync account handling [skip ci] * remove legacy monero account and address list UI * rework BTC account balance refres * avoid unnecessary BTC account reloads * refactor account header in addresses page * fix blank popup when editing an account * fix: dedupe UTXO balance * minor fix * add Bitcoin current account API * Apply batched suggestions from code review [skip ci] Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com> * address PR review comments [skip ci] * remove account customizer and fix accounts init * restrict extra BTC accounts to SegWit * add BTC multi-account toggle * Fix BTC sync gating and account balance update * minor fix * Update electrum_wallet.dart * store selected account on WalletInfo * Refine wallet account reset visibility * refactor BTC address prep and move accounts page * refactor account stack and customizer routing * migrate legacy Lightning card styles * unify dashboard account change state * fix account routing and Electrum balances * fix account setup and wallet cards UI * disable Bitcoin Accounts for all hardware * merge conflicts fix * minor fixes * update cards_view [skip ci] * reverted cards view update [skip ci] * fix asset name * moved the transaction filtering into the electrum wallet * localization * disable accounts for watch-only wallets * fix: stop card render from switching the wallet account * fix: restore Lightning transactions in tx history * minor fix * fix: skip duplicate legacy address generation [skip ci] * fix: correct account balance/design mismatch bugs * addressing review comments --------- Co-authored-by: Robert Malikowski <malikowskirobert@gmail.com> Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
214 lines
8.5 KiB
Dart
214 lines
8.5 KiB
Dart
import 'package:cake_wallet/core/auth_service.dart';
|
|
import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item.dart';
|
|
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/modal_navigator.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/widgets/cake_image_widget.dart';
|
|
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:cw_core/wallet_type.dart";
|
|
import 'package:flutter/material.dart';
|
|
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
|
|
|
|
bool _trueFunc(DashboardViewModel _) => true;
|
|
|
|
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 _requiresKeyImageSync(DashboardViewModel vm) =>
|
|
vm.wallet.type == WalletType.monero &&
|
|
[HardwareWalletType.cupcake, HardwareWalletType.trezor].contains(vm.wallet.hardwareWalletType);
|
|
|
|
class SettingsListItem {
|
|
const SettingsListItem(
|
|
this.iconPath,
|
|
this.title,
|
|
this.route, {
|
|
this.requireAuth = false,
|
|
this.use2fa = _falseFunc,
|
|
this.condition = _trueFunc,
|
|
this.routeArgs,
|
|
this.routeArgsBuilder,
|
|
});
|
|
|
|
final String iconPath;
|
|
final String title;
|
|
final String route;
|
|
final Object? routeArgs;
|
|
final Object? Function(DashboardViewModel)? routeArgsBuilder;
|
|
final bool requireAuth;
|
|
final bool Function(DashboardViewModel) use2fa;
|
|
final bool Function(DashboardViewModel) condition;
|
|
}
|
|
|
|
class SettingsSectionData {
|
|
const SettingsSectionData(this.title, this.titleIconPath, this.items);
|
|
|
|
final String title;
|
|
final String titleIconPath;
|
|
final List<SettingsListItem> items;
|
|
|
|
static SettingsSectionData walletSettings =
|
|
SettingsSectionData(S.current.wallet_settings, "assets/new-ui/wallet-setting.svg", [
|
|
SettingsListItem(
|
|
"assets/new-ui/settings_row_icons/accounts.svg",
|
|
S.current.accounts,
|
|
Routes.walletAccountsPage,
|
|
condition: (vm) => vm.wallet.hasAccountsSupport,
|
|
routeArgsBuilder: (vm) => vm,
|
|
),
|
|
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.recovery_and_keys,
|
|
Routes.showKeysDisclaimer),
|
|
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/sync-balance.svg",
|
|
S.current.resync_device,
|
|
Routes.syncKeyImagesDevices,
|
|
routeArgs: {'export-outputs': 'export-outputs'},
|
|
condition: _requiresKeyImageSync,
|
|
),
|
|
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/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),
|
|
SettingsListItem("assets/new-ui/settings_row_icons/security.svg", S.current.security,
|
|
Routes.securityBackupPage),
|
|
SettingsListItem("assets/new-ui/settings_row_icons/backup.svg", S.current.backup, Routes.backup,
|
|
requireAuth: true,
|
|
use2fa: (vm) => vm.settingsStore.shouldRequireTOTP2FAForAllSecurityAndBackupSettings),
|
|
]);
|
|
|
|
static SettingsSectionData otherSettings = SettingsSectionData("", "", [
|
|
SettingsListItem(
|
|
"assets/new-ui/settings_row_icons/support.svg", S.current.settings_support, Routes.support),
|
|
SettingsListItem(
|
|
"assets/new-ui/settings_row_icons/info.svg", S.current.about, Routes.aboutPage),
|
|
]);
|
|
|
|
static List<SettingsSectionData> all = [walletSettings, appSettings, otherSettings];
|
|
}
|
|
|
|
class NewSettingsPage extends StatelessWidget {
|
|
const NewSettingsPage({super.key, required this.dashboardViewModel, required this.authService});
|
|
|
|
final DashboardViewModel dashboardViewModel;
|
|
final AuthService authService;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return ModalNavigator(
|
|
parentContext: context,
|
|
rootPage: SettingsMainPage(
|
|
dashboardViewModel: dashboardViewModel,
|
|
authService: authService,
|
|
));
|
|
}
|
|
}
|
|
|
|
class SettingsMainPage extends StatelessWidget {
|
|
const SettingsMainPage({super.key, required this.dashboardViewModel, required this.authService});
|
|
|
|
final DashboardViewModel dashboardViewModel;
|
|
final AuthService authService;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
List<ListItem> buildItems(SettingsSectionData section) => section.items
|
|
.map((item) => item.condition(dashboardViewModel)
|
|
? ListItemRegularRow(
|
|
keyValue: item.route,
|
|
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.routeArgsBuilder?.call(dashboardViewModel) ?? item.routeArgs,
|
|
);
|
|
}
|
|
}
|
|
})
|
|
: null)
|
|
.whereType<ListItem>()
|
|
.toList();
|
|
|
|
return Container(
|
|
color: Theme.of(context).colorScheme.surface,
|
|
child: Column(children: [
|
|
ModalTopBar(
|
|
title: S.of(context).settings_title,
|
|
leadingIcon: Icon(Icons.close),
|
|
leadingSemanticLabel: S.of(context).close,
|
|
onLeadingPressed: Navigator.of(context, rootNavigator: true).pop,
|
|
onTrailingPressed: () {},
|
|
),
|
|
Expanded(
|
|
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: [
|
|
CakeImageWidget(
|
|
imageUrl: 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(),
|
|
),
|
|
),
|
|
]),
|
|
),
|
|
]),
|
|
);
|
|
}
|
|
}
|