mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-26 06:08:40 +01:00
CW-1468 Home Screen Top Bar Layout (#3576)
* Improve homescreen layout and account access * Add homescreen layout regression tests * address feedback
This commit is contained in:
@@ -602,6 +602,13 @@ Future<void> setup({
|
||||
getIt.registerFactory<AccountCreationModal>(() => AccountCreationModal(
|
||||
accountEditOrCreateViewModel: getIt.get<MoneroAccountEditOrCreateViewModel>()));
|
||||
|
||||
getIt.registerFactoryParam<AccountCustomizer, DashboardViewModel, void>(
|
||||
(dashboardViewModel, _) => AccountCustomizer(
|
||||
accountListViewModel: getIt.get<MoneroAccountListViewModel>(),
|
||||
dashboardViewModel: dashboardViewModel,
|
||||
),
|
||||
);
|
||||
|
||||
getIt.registerFactory<LightningUsernameBloc>(
|
||||
() => LightningUsernameBloc(getIt.get<AppStore>().wallet!));
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import 'dart:ui';
|
||||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/monero/monero.dart';
|
||||
import 'package:cake_wallet/new-ui/pages/card_customizer.dart';
|
||||
import 'package:cake_wallet/new-ui/viewmodels/card_customizer/card_customizer_bloc.dart';
|
||||
import 'package:cake_wallet/new-ui/widgets/coins_page/cards/balance_card.dart';
|
||||
@@ -24,7 +23,6 @@ import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
|
||||
|
||||
class AccountCustomizerListItem {
|
||||
@@ -38,13 +36,9 @@ class AccountCustomizerListItem {
|
||||
|
||||
class AccountCustomizer extends StatefulWidget {
|
||||
const AccountCustomizer(
|
||||
{super.key,
|
||||
required this.accountListViewModel,
|
||||
required this.accountEditOrCreateViewModel,
|
||||
required this.dashboardViewModel});
|
||||
{super.key, required this.accountListViewModel, required this.dashboardViewModel});
|
||||
|
||||
final MoneroAccountListViewModel accountListViewModel;
|
||||
final MoneroAccountEditOrCreateViewModel accountEditOrCreateViewModel;
|
||||
final DashboardViewModel dashboardViewModel;
|
||||
|
||||
@override
|
||||
@@ -62,7 +56,7 @@ class _AccountCustomizerState extends State<AccountCustomizer> {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
loadCards();
|
||||
final activeId = monero!.getCurrentAccount(widget.dashboardViewModel.wallet).id;
|
||||
final activeId = widget.accountListViewModel.selected.id;
|
||||
for (int i = 0; i < _items.length - 1; i++) {
|
||||
if (_items[i].accountListItem.id == activeId) {
|
||||
final lastIndex = _items.length - 1;
|
||||
|
||||
@@ -14,11 +14,9 @@ import 'package:cake_wallet/new-ui/widgets/coins_page/cards/cards_view.dart';
|
||||
import 'package:cake_wallet/new-ui/widgets/coins_page/mweb_ad.dart';
|
||||
import 'package:cake_wallet/new-ui/widgets/coins_page/top_bar_widget/top_bar.dart';
|
||||
import 'package:cake_wallet/new-ui/widgets/coins_page/unconfirmed_balance_widget.dart';
|
||||
import 'package:cake_wallet/new-ui/widgets/coins_page/wallet_info.dart';
|
||||
import "package:cake_wallet/new-ui/widgets/coins_page/zcash_migration_modal.dart";
|
||||
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/nft_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/monero_account_list/monero_account_edit_or_create_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/monero_account_list/monero_account_list_view_model.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -115,6 +113,7 @@ class _NewHomePageState extends State<NewHomePage> {
|
||||
spacing: 24.0,
|
||||
children: [
|
||||
TopBar(
|
||||
key: ValueKey(widget.dashboardViewModel.wallet.id),
|
||||
dashboardViewModel: widget.dashboardViewModel,
|
||||
lightningMode: _lightningMode,
|
||||
onLightningSwitchPress: () {
|
||||
@@ -122,8 +121,8 @@ class _NewHomePageState extends State<NewHomePage> {
|
||||
_lightningMode = !_lightningMode;
|
||||
});
|
||||
},
|
||||
onSettingsButtonPress: () {
|
||||
CupertinoScaffold.showCupertinoModalBottomSheet(
|
||||
onSettingsButtonPress: () async {
|
||||
await CupertinoScaffold.showCupertinoModalBottomSheet(
|
||||
context: context,
|
||||
barrierColor: Colors.black.withAlpha(85),
|
||||
builder: (context) => FractionallySizedBox(
|
||||
@@ -133,70 +132,77 @@ class _NewHomePageState extends State<NewHomePage> {
|
||||
authService: getIt.get<AuthService>(),
|
||||
))),
|
||||
);
|
||||
|
||||
if (!mounted) {
|
||||
return;
|
||||
}
|
||||
_setAccountViewModel();
|
||||
await widget.dashboardViewModel.loadCardDesigns();
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
},
|
||||
),
|
||||
Observer(
|
||||
builder: (_) => WalletInfoBar(
|
||||
lightningMode: _lightningMode,
|
||||
hardwareWalletType: widget.dashboardViewModel.wallet.hardwareWalletType,
|
||||
name: widget.dashboardViewModel.wallet.name,
|
||||
hasCustomize: accountListViewModel != null,
|
||||
onCustomizeButtonTap: openAccountCustomizer),
|
||||
),
|
||||
Column(
|
||||
spacing: 20,
|
||||
children: [
|
||||
Observer(
|
||||
builder: (_) => CardsView(
|
||||
key: ValueKey(widget.dashboardViewModel.wallet.name),
|
||||
onCustomizeTapped: openCardCustomizer,
|
||||
dashboardViewModel: widget.dashboardViewModel,
|
||||
accountListViewModel: accountListViewModel,
|
||||
onCompactModeBackgroundCardsTapped: openAccountCustomizer,
|
||||
lightningMode: _lightningMode,
|
||||
),
|
||||
),
|
||||
Observer(builder: (_) {
|
||||
return AnimatedSize(
|
||||
duration: Duration(milliseconds: 150),
|
||||
curve: Curves.easeInOutCubic,
|
||||
child: (widget.dashboardViewModel.shouldShowBalanceHiddenMessage)
|
||||
? Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 12,
|
||||
width: double.infinity,
|
||||
),
|
||||
Text(
|
||||
S.of(context).long_press_show_balance,
|
||||
style: TextStyle(
|
||||
color:
|
||||
Theme.of(context).colorScheme.onSurfaceVariant),
|
||||
)
|
||||
],
|
||||
)
|
||||
: SizedBox(width: double.infinity),
|
||||
);
|
||||
}),
|
||||
UnconfirmedBalanceWidget(
|
||||
dashboardViewModel: widget.dashboardViewModel,
|
||||
),
|
||||
],
|
||||
),
|
||||
Observer(
|
||||
builder: (_) {
|
||||
return Column(
|
||||
Column(
|
||||
children: [
|
||||
CoinActionRow(
|
||||
lightningMode: _lightningMode,
|
||||
showSwap: widget.dashboardViewModel.isEnabledSwapAction,
|
||||
walletType: widget.dashboardViewModel.wallet.type,
|
||||
Observer(
|
||||
builder: (_) => CardsView(
|
||||
key: ValueKey(widget.dashboardViewModel.wallet.name),
|
||||
onCustomizeTapped: openCardCustomizer,
|
||||
dashboardViewModel: widget.dashboardViewModel,
|
||||
accountListViewModel: accountListViewModel,
|
||||
onCompactModeBackgroundCardsTapped: openAccountCustomizer,
|
||||
lightningMode: _lightningMode,
|
||||
),
|
||||
),
|
||||
MwebAd(
|
||||
Observer(builder: (_) {
|
||||
return AnimatedSize(
|
||||
duration: Duration(milliseconds: 150),
|
||||
curve: Curves.easeInOutCubic,
|
||||
child: (widget.dashboardViewModel.shouldShowBalanceHiddenMessage)
|
||||
? Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 12,
|
||||
width: double.infinity,
|
||||
),
|
||||
Text(
|
||||
S.of(context).long_press_show_balance,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onSurfaceVariant),
|
||||
)
|
||||
],
|
||||
)
|
||||
: SizedBox(width: double.infinity),
|
||||
);
|
||||
}),
|
||||
UnconfirmedBalanceWidget(
|
||||
dashboardViewModel: widget.dashboardViewModel,
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
Observer(
|
||||
builder: (_) {
|
||||
return Column(
|
||||
children: [
|
||||
CoinActionRow(
|
||||
lightningMode: _lightningMode,
|
||||
showSwap: widget.dashboardViewModel.isEnabledSwapAction,
|
||||
walletType: widget.dashboardViewModel.wallet.type,
|
||||
),
|
||||
MwebAd(
|
||||
dashboardViewModel: widget.dashboardViewModel,
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -234,7 +240,12 @@ class _NewHomePageState extends State<NewHomePage> {
|
||||
);
|
||||
}
|
||||
|
||||
void openAccountCustomizer() async {
|
||||
Future<void> openAccountCustomizer() async {
|
||||
final accountList = accountListViewModel;
|
||||
if (accountList == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
await CupertinoScaffold.showCupertinoModalBottomSheet(
|
||||
barrierColor: Colors.black.withAlpha(60),
|
||||
context: context,
|
||||
@@ -243,15 +254,15 @@ class _NewHomePageState extends State<NewHomePage> {
|
||||
parentContext: context,
|
||||
heightMode: ModalHeightModes.fullScreen,
|
||||
rootPage: Material(
|
||||
child: AccountCustomizer(
|
||||
accountListViewModel: accountListViewModel!,
|
||||
accountEditOrCreateViewModel: getIt.get<MoneroAccountEditOrCreateViewModel>(),
|
||||
dashboardViewModel: widget.dashboardViewModel,
|
||||
)),
|
||||
child: AccountCustomizer(
|
||||
accountListViewModel: accountList,
|
||||
dashboardViewModel: widget.dashboardViewModel,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
widget.dashboardViewModel.loadCardDesigns();
|
||||
await widget.dashboardViewModel.loadCardDesigns();
|
||||
}
|
||||
|
||||
void openCardCustomizer() async {
|
||||
|
||||
@@ -25,6 +25,8 @@ bool _hasMweb(DashboardViewModel vm) => vm.hasMweb;
|
||||
|
||||
bool _hasWalletConnect(DashboardViewModel vm) => vm.hasWalletConnect;
|
||||
|
||||
bool _hasAccounts(DashboardViewModel vm) => vm.balanceViewModel.hasAccounts;
|
||||
|
||||
bool _requiresKeyImageSync(DashboardViewModel vm) =>
|
||||
vm.wallet.type == WalletType.monero &&
|
||||
[HardwareWalletType.cupcake, HardwareWalletType.trezor].contains(vm.wallet.hardwareWalletType);
|
||||
@@ -38,12 +40,14 @@ class SettingsListItem {
|
||||
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;
|
||||
@@ -58,6 +62,13 @@ class SettingsSectionData {
|
||||
|
||||
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.accountCustomizer,
|
||||
condition: _hasAccounts,
|
||||
routeArgsBuilder: (vm) => vm,
|
||||
),
|
||||
SettingsListItem(
|
||||
"assets/new-ui/settings_row_icons/nodes.svg", S.current.nodes, Routes.manageNodes),
|
||||
SettingsListItem(
|
||||
@@ -148,7 +159,11 @@ class SettingsMainPage extends StatelessWidget {
|
||||
conditionToDetermineIfToUse2FA: item.use2fa(dashboardViewModel),
|
||||
route: item.route);
|
||||
} else {
|
||||
Navigator.of(context).pushNamed(item.route, arguments: item.routeArgs);
|
||||
Navigator.of(context).pushNamed(
|
||||
item.route,
|
||||
arguments:
|
||||
item.routeArgsBuilder?.call(dashboardViewModel) ?? item.routeArgs,
|
||||
);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -26,7 +26,12 @@ class AssetsTopBar extends StatelessWidget {
|
||||
|
||||
return SliverToBoxAdapter(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(top: 32.0, bottom: 0.0, left: 12.0, right: 18.0),
|
||||
padding: const EdgeInsets.only(
|
||||
top: 20,
|
||||
bottom: 0,
|
||||
left: 12,
|
||||
right: 18,
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
|
||||
@@ -20,7 +20,7 @@ class HistoryTopBar extends StatelessWidget {
|
||||
onTap: onTap,
|
||||
behavior: HitTestBehavior.opaque,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 16, right: 16, top: 24),
|
||||
padding: const EdgeInsets.only(left: 16, right: 16, top: 20),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.vertical(
|
||||
|
||||
@@ -30,64 +30,59 @@ class LightningSwitcher extends StatelessWidget {
|
||||
shape:
|
||||
RoundedSuperellipseBorder(borderRadius: BorderRadiusGeometry.circular(900.0)),
|
||||
color: Theme.of(context).colorScheme.surfaceContainer),
|
||||
width: 70,
|
||||
width: 63,
|
||||
height: 36,
|
||||
padding: EdgeInsets.symmetric(vertical: 2),
|
||||
padding: const EdgeInsets.all(4.5),
|
||||
child: Stack(
|
||||
children: [
|
||||
AnimatedContainer(
|
||||
alignment: Alignment.centerRight,
|
||||
margin: EdgeInsets.only(left: lightningMode ? 36 : 2),
|
||||
duration: Duration(milliseconds: 250),
|
||||
margin: EdgeInsets.only(left: lightningMode ? 27 : 0),
|
||||
duration: const Duration(milliseconds: 250),
|
||||
curve: Curves.easeOutCubic,
|
||||
width: 32,
|
||||
height: 32,
|
||||
// height: double.infinity,
|
||||
width: 27,
|
||||
height: 27,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(9999990.0)),
|
||||
color: Theme.of(context).colorScheme.primary),
|
||||
),
|
||||
Container(
|
||||
child: Row(
|
||||
spacing: 2.0,
|
||||
children: [
|
||||
SizedBox(),
|
||||
AnimatedSwitcher(
|
||||
duration: Duration(milliseconds: 150),
|
||||
transitionBuilder: (child, animation) =>
|
||||
FadeTransition(opacity: animation, child: child),
|
||||
child: CakeImageWidget(
|
||||
imageUrl: 'assets/new-ui/switcher-bitcoin.svg',
|
||||
key: ValueKey(lightningMode),
|
||||
width: 32,
|
||||
height: 32,
|
||||
colorFilter: ColorFilter.mode(
|
||||
lightningMode
|
||||
? Theme.of(context).colorScheme.primary
|
||||
: Theme.of(context).colorScheme.surfaceContainer,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 150),
|
||||
transitionBuilder: (child, animation) =>
|
||||
FadeTransition(opacity: animation, child: child),
|
||||
child: CakeImageWidget(
|
||||
imageUrl: "assets/new-ui/switcher-bitcoin.svg",
|
||||
key: ValueKey(lightningMode),
|
||||
width: 27,
|
||||
height: 27,
|
||||
colorFilter: ColorFilter.mode(
|
||||
lightningMode
|
||||
? Theme.of(context).colorScheme.primary
|
||||
: Theme.of(context).colorScheme.surfaceContainer,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
),
|
||||
AnimatedSwitcher(
|
||||
duration: Duration(milliseconds: 150),
|
||||
transitionBuilder: (child, animation) =>
|
||||
FadeTransition(opacity: animation, child: child),
|
||||
child: CakeImageWidget(
|
||||
imageUrl: 'assets/new-ui/switcher-lightning.svg',
|
||||
key: ValueKey(lightningMode),
|
||||
width: 32,
|
||||
height: 32,
|
||||
colorFilter: ColorFilter.mode(
|
||||
lightningMode
|
||||
? Theme.of(context).colorScheme.surfaceContainer
|
||||
: Theme.of(context).colorScheme.primary,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
),
|
||||
AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 150),
|
||||
transitionBuilder: (child, animation) =>
|
||||
FadeTransition(opacity: animation, child: child),
|
||||
child: CakeImageWidget(
|
||||
imageUrl: "assets/new-ui/switcher-lightning.svg",
|
||||
key: ValueKey(lightningMode),
|
||||
width: 27,
|
||||
height: 27,
|
||||
colorFilter: ColorFilter.mode(
|
||||
lightningMode
|
||||
? Theme.of(context).colorScheme.surfaceContainer
|
||||
: Theme.of(context).colorScheme.primary,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/generated/i18n.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/themes/core/theme_extension.dart";
|
||||
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
|
||||
import 'package:cw_core/sync_status.dart';
|
||||
import "package:flutter/cupertino.dart";
|
||||
@@ -11,11 +12,11 @@ import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
|
||||
|
||||
class SyncBar extends StatelessWidget {
|
||||
SyncBar({
|
||||
super.key,
|
||||
const SyncBar({
|
||||
required this.dashboardViewModel,
|
||||
required this.isSyncHeavy,
|
||||
required this.showSyncedMessage,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final DashboardViewModel dashboardViewModel;
|
||||
@@ -46,106 +47,126 @@ class SyncBar extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => Observer(
|
||||
builder: (_) {
|
||||
final status = dashboardViewModel.status;
|
||||
final Widget? icon = _getIcon(context, status.runtimeType);
|
||||
builder: (_) {
|
||||
final status = dashboardViewModel.status;
|
||||
if (!_showFullBar) {
|
||||
return _buildCompactBar(context);
|
||||
}
|
||||
|
||||
return Expanded(
|
||||
child: Stack(
|
||||
alignment: Alignment.centerLeft,
|
||||
children: [
|
||||
if (!_showFullBar()) _buildCompactBar(context),
|
||||
if (_showFullBar())
|
||||
// A single node: the localized status text (plus any active
|
||||
// Tor/MWEB/Silent Payments badge) is the label, and the hint says
|
||||
// where tapping leads. Everything inside is redundant with it.
|
||||
Semantics(
|
||||
button: true,
|
||||
label: _statusSemanticsLabel(context, status),
|
||||
hint: S.of(context).manage_nodes,
|
||||
onTap: () => _openNodeManagement(context),
|
||||
child: ExcludeSemantics(
|
||||
child: GestureDetector(
|
||||
onTap: () => _openNodeManagement(context),
|
||||
child: AnimatedSwitcher(
|
||||
duration: Duration(milliseconds: 100),
|
||||
child: Container(
|
||||
key: ValueKey(status.runtimeType),
|
||||
height: 36,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(9999),
|
||||
border: _getBorder(context, status.runtimeType),
|
||||
color: _getBackgroundColor(context, status.runtimeType),
|
||||
),
|
||||
child: Row(
|
||||
spacing: 10,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
if (icon != null) icon,
|
||||
// if (dashboardViewModel.silentPaymentsScanningActive &&
|
||||
// progressStatuses.contains(status.runtimeType)) ...[
|
||||
// Text(
|
||||
// "${(status.progress() * 100).toInt()}%",
|
||||
// style: TextStyle(fontSize: 12, color: Color(0xFFEFBA5E)),
|
||||
// ),
|
||||
// Text(
|
||||
// "·",
|
||||
// style: TextStyle(fontSize: 12),
|
||||
// )
|
||||
// ],
|
||||
Text(
|
||||
syncStatusTitle(status,
|
||||
dashboardViewModel.settingsStore.syncStatusDisplayMode),
|
||||
style: _getTextStyle(context, status.runtimeType),
|
||||
final Widget? icon = _getIcon(context, status.runtimeType);
|
||||
final statusTitle = _statusTitle(context, status);
|
||||
final silentPaymentsProgress = _silentPaymentsProgress(status);
|
||||
final barHeight = silentPaymentsProgress == null ? 36.0 : 40.0;
|
||||
|
||||
// A single node: the localized status text (plus any active
|
||||
// Tor/MWEB/Silent Payments badge) is the label, and the hint says
|
||||
// where tapping leads. Everything inside is redundant with it.
|
||||
return Semantics(
|
||||
button: true,
|
||||
label: _statusSemanticsLabel(context, status, statusTitle),
|
||||
value: silentPaymentsProgress,
|
||||
hint: S.of(context).manage_nodes,
|
||||
onTap: () => _openNodeManagement(context),
|
||||
child: ExcludeSemantics(
|
||||
child: GestureDetector(
|
||||
onTap: () => _openNodeManagement(context),
|
||||
child: AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 100),
|
||||
child: OverflowBox(
|
||||
key: ValueKey(status.runtimeType),
|
||||
alignment: Alignment.center,
|
||||
minHeight: barHeight,
|
||||
maxHeight: barHeight,
|
||||
child: Container(
|
||||
height: barHeight,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(9999),
|
||||
border: _getBorder(context, status.runtimeType),
|
||||
color: _getBackgroundColor(context, status.runtimeType),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||
child: Row(
|
||||
spacing: 8,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
if (icon != null) icon,
|
||||
if (silentPaymentsProgress != null) ...[
|
||||
Text(
|
||||
silentPaymentsProgress,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: context.customColors.warningOutlineColor,
|
||||
),
|
||||
],
|
||||
),
|
||||
Text(
|
||||
"·",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
Flexible(
|
||||
child: Text(
|
||||
statusTitle,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: _getTextStyle(context, status.runtimeType),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
void _openNodeManagement(BuildContext context) =>
|
||||
CupertinoScaffold.showCupertinoModalBottomSheet(
|
||||
context: context,
|
||||
barrierColor: Colors.black.withAlpha(85),
|
||||
builder: (context) => FractionallySizedBox(
|
||||
child: Material(
|
||||
child: getIt.get<ManageNodesPage>(param1: false),
|
||||
)));
|
||||
void _openNodeManagement(BuildContext context) {
|
||||
CupertinoScaffold.showCupertinoModalBottomSheet(
|
||||
context: context,
|
||||
barrierColor: Colors.black.withAlpha(85),
|
||||
builder: (context) => FractionallySizedBox(
|
||||
child: Material(
|
||||
child: getIt.get<ManageNodesPage>(param1: false),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Compact mode shows sync state with a pulsing dot (and a Tor glyph) only, so
|
||||
/// the whole row needs a text equivalent.
|
||||
Widget _buildCompactBar(BuildContext context) {
|
||||
final row = Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
spacing: 6,
|
||||
children: [
|
||||
if (dashboardViewModel.isTorEnabled)
|
||||
CakeImageWidget(
|
||||
const CakeImageWidget(
|
||||
imageUrl: "assets/new-ui/tor.svg",
|
||||
width: 20,
|
||||
height: 20,
|
||||
),
|
||||
if (_showDot()) const CupertinoActivityIndicator(radius: 8),
|
||||
if(_showLightSyncCheck()) const Icon(Icons.check, color: syncedColor, size: 18),
|
||||
],
|
||||
if (_showLightSyncCheck()) const Icon(Icons.check, color: syncedColor, size: 18),
|
||||
],
|
||||
);
|
||||
|
||||
final label = _joinLabels([
|
||||
if (dashboardViewModel.isTorEnabled) S.of(context).tor_connection,
|
||||
if (_showDot()) S.of(context).synchronizing,
|
||||
if (_showLightSyncCheck()) S.of(context).sync_synced,
|
||||
]);
|
||||
|
||||
if (label.isEmpty) return row;
|
||||
if (label.isEmpty) {
|
||||
return row;
|
||||
}
|
||||
|
||||
return Semantics(label: label, child: ExcludeSemantics(child: row));
|
||||
}
|
||||
@@ -153,11 +174,17 @@ class SyncBar extends StatelessWidget {
|
||||
bool get _isShowingSyncedMessage =>
|
||||
showSyncedMessage && dashboardViewModel.status.runtimeType == SyncedSyncStatus;
|
||||
|
||||
String _statusSemanticsLabel(BuildContext context, SyncStatus status) {
|
||||
String _statusTitle(BuildContext context, SyncStatus status) {
|
||||
final title = syncStatusTitle(status, dashboardViewModel.settingsStore.syncStatusDisplayMode);
|
||||
|
||||
return title.isNotEmpty ? title : S.of(context).synchronizing;
|
||||
}
|
||||
|
||||
String _statusSemanticsLabel(BuildContext context, SyncStatus status, String statusTitle) {
|
||||
final isFailure = failStatuses.contains(status.runtimeType);
|
||||
|
||||
return _joinLabels([
|
||||
syncStatusTitle(status, dashboardViewModel.settingsStore.syncStatusDisplayMode),
|
||||
statusTitle,
|
||||
if (!isFailure && dashboardViewModel.isTorEnabled) S.of(context).tor_connection,
|
||||
if (!isFailure && dashboardViewModel.hasMweb) S.of(context).litecoin_mweb,
|
||||
if (!isFailure && dashboardViewModel.hasSilentPayments) S.of(context).silent_payments,
|
||||
@@ -166,6 +193,16 @@ class SyncBar extends StatelessWidget {
|
||||
|
||||
String _joinLabels(List<String> parts) => parts.where((part) => part.isNotEmpty).join(", ");
|
||||
|
||||
String? _silentPaymentsProgress(SyncStatus status) {
|
||||
if (!dashboardViewModel.hasSilentPayments ||
|
||||
!dashboardViewModel.silentPaymentsScanningActive ||
|
||||
status is! SyncingSyncStatus) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return "${(status.progress() * 100).toInt()}%";
|
||||
}
|
||||
|
||||
Color? _getBackgroundColor(BuildContext context, Type status) {
|
||||
if (failStatuses.contains(status)) {
|
||||
return Theme.of(context).colorScheme.errorContainer.withAlpha(64);
|
||||
@@ -192,14 +229,12 @@ class SyncBar extends StatelessWidget {
|
||||
color = Theme.of(context).colorScheme.onSurfaceVariant;
|
||||
}
|
||||
|
||||
return TextStyle(
|
||||
fontSize: 12, fontWeight: FontWeight.w400, color: color);
|
||||
return TextStyle(fontSize: 12, fontWeight: FontWeight.w400, color: color);
|
||||
}
|
||||
|
||||
Widget? _getIcon(BuildContext context, Type status) {
|
||||
|
||||
if(status == SyncedSyncStatus) {
|
||||
return Icon(Icons.check, color: syncedColor, size: 12);
|
||||
if (status == SyncedSyncStatus) {
|
||||
return const Icon(Icons.check, color: syncedColor, size: 12);
|
||||
}
|
||||
|
||||
if (status == LostConnectionSyncStatus) {
|
||||
@@ -219,22 +254,35 @@ class SyncBar extends StatelessWidget {
|
||||
final List<Widget> children = [];
|
||||
|
||||
if (dashboardViewModel.isTorEnabled) {
|
||||
children.add(CakeImageWidget(
|
||||
children.add(
|
||||
const CakeImageWidget(
|
||||
imageUrl: "assets/new-ui/tor_sync.svg",
|
||||
colorFilter: ColorFilter.mode(Color(0xFF8A38F5), BlendMode.srcIn)));
|
||||
colorFilter: ColorFilter.mode(Color(0xFF8A38F5), BlendMode.srcIn),
|
||||
),
|
||||
);
|
||||
}
|
||||
if (dashboardViewModel.hasMweb) {
|
||||
children.add(CakeImageWidget(
|
||||
imageUrl: "assets/new-ui/mweb_sync.svg",
|
||||
colorFilter:
|
||||
ColorFilter.mode(Theme.of(context).colorScheme.onSurfaceVariant, BlendMode.srcIn),
|
||||
));
|
||||
children.add(
|
||||
CakeImageWidget(
|
||||
imageUrl: "assets/new-ui/mweb_sync.svg",
|
||||
colorFilter:
|
||||
ColorFilter.mode(Theme.of(context).colorScheme.onSurfaceVariant, BlendMode.srcIn),
|
||||
),
|
||||
);
|
||||
}
|
||||
if (dashboardViewModel.hasSilentPayments) {
|
||||
children.add(CakeImageWidget(
|
||||
imageUrl: "assets/new-ui/silent_sync.svg",
|
||||
colorFilter: ColorFilter.mode(Color(0xFFEFBA5E), BlendMode.srcIn),
|
||||
));
|
||||
children.add(
|
||||
CakeImageWidget(
|
||||
imageUrl: "assets/new-ui/silent_sync.svg",
|
||||
width: 16,
|
||||
height: 16,
|
||||
colorFilter: ColorFilter.mode(context.customColors.warningOutlineColor, BlendMode.srcIn),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if (children.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Row(
|
||||
@@ -243,15 +291,16 @@ class SyncBar extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
bool _showFullBar() {
|
||||
if (dashboardViewModel.status.runtimeType == SyncedSyncStatus)
|
||||
bool get _showFullBar {
|
||||
if (dashboardViewModel.status.runtimeType == SyncedSyncStatus) {
|
||||
return isSyncHeavy && _isShowingSyncedMessage;
|
||||
}
|
||||
|
||||
return isSyncHeavy || failStatuses.contains(dashboardViewModel.status.runtimeType);
|
||||
}
|
||||
|
||||
bool _showDot() =>
|
||||
!isSyncHeavy && progressStatuses.contains(dashboardViewModel.status.runtimeType);
|
||||
|
||||
bool _showLightSyncCheck() =>
|
||||
!isSyncHeavy && _isShowingSyncedMessage;
|
||||
bool _showLightSyncCheck() => !isSyncHeavy && _isShowingSyncedMessage;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/new-ui/widgets/coins_page/top_bar_widget/chain_icon.dart';
|
||||
import 'package:cake_wallet/new-ui/widgets/coins_page/top_bar_widget/lightning_switcher.dart';
|
||||
import 'package:cake_wallet/new-ui/widgets/coins_page/top_bar_widget/sync_bar.dart';
|
||||
import "package:cake_wallet/new-ui/widgets/coins_page/wallet_info.dart";
|
||||
import 'package:cake_wallet/new-ui/widgets/modern_button.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
|
||||
import 'package:cw_core/sync_status.dart';
|
||||
@@ -15,11 +16,11 @@ import 'package:mobx/mobx.dart';
|
||||
|
||||
class TopBar extends StatefulWidget {
|
||||
const TopBar({
|
||||
super.key,
|
||||
required this.lightningMode,
|
||||
required this.onLightningSwitchPress,
|
||||
required this.dashboardViewModel,
|
||||
required this.onSettingsButtonPress,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final bool lightningMode;
|
||||
@@ -36,25 +37,59 @@ class _TopBarState extends State<TopBar> {
|
||||
|
||||
bool showSyncedMessage = false;
|
||||
Timer? syncedMessageTimer;
|
||||
late final ReactionDisposer? _statusReactionDisposer;
|
||||
ReactionDisposer? _statusReactionDisposer;
|
||||
|
||||
bool get replacesWalletName {
|
||||
final status = widget.dashboardViewModel.status.runtimeType;
|
||||
if (status == SyncedSyncStatus) {
|
||||
return showSyncedMessage;
|
||||
}
|
||||
|
||||
return widget.dashboardViewModel.isSyncHeavy ||
|
||||
SyncBar.progressStatuses.contains(status) ||
|
||||
SyncBar.failStatuses.contains(status);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_bindStatusReaction();
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(covariant TopBar oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
|
||||
if (identical(oldWidget.dashboardViewModel, widget.dashboardViewModel)) {
|
||||
return;
|
||||
}
|
||||
|
||||
syncedMessageTimer?.cancel();
|
||||
syncedMessageTimer = null;
|
||||
showSyncedMessage = false;
|
||||
_statusReactionDisposer?.call();
|
||||
_bindStatusReaction();
|
||||
}
|
||||
|
||||
void _bindStatusReaction() {
|
||||
_statusReactionDisposer = reaction(
|
||||
(_) => widget.dashboardViewModel.status.runtimeType,
|
||||
(status) {
|
||||
syncedMessageTimer?.cancel();
|
||||
syncedMessageTimer = null;
|
||||
|
||||
if (status == SyncedSyncStatus) {
|
||||
if(mounted) {
|
||||
if (mounted) {
|
||||
setState(() => showSyncedMessage = true);
|
||||
}
|
||||
syncedMessageTimer =
|
||||
Timer(syncedMessageDuration, () => setState(() => showSyncedMessage = false));
|
||||
syncedMessageTimer = Timer(syncedMessageDuration, () {
|
||||
syncedMessageTimer = null;
|
||||
if (mounted) {
|
||||
setState(() => showSyncedMessage = false);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if(mounted) {
|
||||
if (mounted) {
|
||||
setState(() => showSyncedMessage = false);
|
||||
}
|
||||
}
|
||||
@@ -65,51 +100,90 @@ class _TopBarState extends State<TopBar> {
|
||||
@override
|
||||
void dispose() {
|
||||
syncedMessageTimer?.cancel();
|
||||
_statusReactionDisposer?.reaction.dispose();
|
||||
syncedMessageTimer = null;
|
||||
_statusReactionDisposer?.call();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => Padding(
|
||||
padding: EdgeInsets.only(
|
||||
bottom: 10, left: 18, right: 18, top: 10 + _additionalTopPadding(context)),
|
||||
child: Observer(
|
||||
builder: (_) => Row(
|
||||
spacing: 12,
|
||||
children: [
|
||||
(widget.dashboardViewModel.hasLightning)
|
||||
? LightningSwitcher(
|
||||
lightningMode: widget.lightningMode,
|
||||
onLightningSwitchPress: widget.onLightningSwitchPress,
|
||||
)
|
||||
: ChainIcon(
|
||||
iconPath: widget.dashboardViewModel.wallet.currency.flatIconPath ?? "",
|
||||
dashboardViewModel: widget.dashboardViewModel,
|
||||
isSyncHeavy: widget.dashboardViewModel.isSyncHeavy,
|
||||
showSyncedMessage: showSyncedMessage),
|
||||
SyncBar(
|
||||
dashboardViewModel: widget.dashboardViewModel,
|
||||
isSyncHeavy: widget.dashboardViewModel.isSyncHeavy,
|
||||
showSyncedMessage: showSyncedMessage,
|
||||
),
|
||||
ModernButton.svg(
|
||||
iconColor: Theme.of(context).colorScheme.primary,
|
||||
size: 36,
|
||||
onPressed: () {
|
||||
HapticFeedback.mediumImpact();
|
||||
widget.onSettingsButtonPress();
|
||||
},
|
||||
svgPath: "assets/new-ui/top-settings.svg",
|
||||
semanticLabel: S.of(context).settings_title,
|
||||
),
|
||||
],
|
||||
padding: EdgeInsets.only(left: 18, right: 18, top: 10 + _additionalTopPadding(context)),
|
||||
child: Observer(
|
||||
builder: (_) => Row(
|
||||
spacing: 12,
|
||||
children: [
|
||||
widget.dashboardViewModel.hasLightning
|
||||
? LightningSwitcher(
|
||||
lightningMode: widget.lightningMode,
|
||||
onLightningSwitchPress: widget.onLightningSwitchPress,
|
||||
)
|
||||
: ChainIcon(
|
||||
iconPath: widget.dashboardViewModel.wallet.currency.flatIconPath ?? "",
|
||||
dashboardViewModel: widget.dashboardViewModel,
|
||||
isSyncHeavy: widget.dashboardViewModel.isSyncHeavy,
|
||||
showSyncedMessage: showSyncedMessage,
|
||||
),
|
||||
Expanded(
|
||||
child: SizedBox(
|
||||
height: 36,
|
||||
child: AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 150),
|
||||
reverseDuration: Duration.zero,
|
||||
layoutBuilder: (currentChild, previousChildren) => Stack(
|
||||
alignment: Alignment.centerLeft,
|
||||
children: [
|
||||
...previousChildren,
|
||||
if (currentChild != null) currentChild,
|
||||
],
|
||||
),
|
||||
child: replacesWalletName
|
||||
? SyncBar(
|
||||
dashboardViewModel: widget.dashboardViewModel,
|
||||
isSyncHeavy: widget.dashboardViewModel.isSyncHeavy,
|
||||
showSyncedMessage: showSyncedMessage,
|
||||
)
|
||||
: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: WalletInfoBar(
|
||||
name: widget.dashboardViewModel.wallet.name,
|
||||
hardwareWalletType:
|
||||
widget.dashboardViewModel.wallet.hardwareWalletType,
|
||||
),
|
||||
),
|
||||
if (widget.dashboardViewModel.isTorEnabled) ...[
|
||||
const SizedBox(width: 6),
|
||||
SyncBar(
|
||||
dashboardViewModel: widget.dashboardViewModel,
|
||||
isSyncHeavy: widget.dashboardViewModel.isSyncHeavy,
|
||||
showSyncedMessage: showSyncedMessage,
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
ModernButton.svg(
|
||||
iconColor: Theme.of(context).colorScheme.primary,
|
||||
size: 36,
|
||||
onPressed: () {
|
||||
HapticFeedback.mediumImpact();
|
||||
widget.onSettingsButtonPress();
|
||||
},
|
||||
svgPath: "assets/new-ui/top-settings.svg",
|
||||
semanticLabel: S.of(context).settings_title,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
);
|
||||
|
||||
//FIXME remove after this gets fixed flutter-side
|
||||
double _additionalTopPadding(BuildContext context) {
|
||||
if (Platform.isIOS && MediaQuery.of(context).viewPadding.top < 12) return 24;
|
||||
if (Platform.isIOS && MediaQuery.of(context).viewPadding.top < 12) {
|
||||
return 24;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,102 +1,67 @@
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/new-ui/widgets/modern_button.dart';
|
||||
import 'package:cake_wallet/src/widgets/cake_image_widget.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
|
||||
class WalletInfoBar extends StatelessWidget {
|
||||
const WalletInfoBar(
|
||||
{super.key,
|
||||
required this.lightningMode,
|
||||
required this.name,
|
||||
required this.hardwareWalletType,
|
||||
required this.onCustomizeButtonTap,
|
||||
required this.hasCustomize});
|
||||
const WalletInfoBar({
|
||||
required this.name,
|
||||
required this.hardwareWalletType,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final bool lightningMode;
|
||||
final String name;
|
||||
final HardwareWalletType? hardwareWalletType;
|
||||
final bool hasCustomize;
|
||||
final VoidCallback onCustomizeButtonTap;
|
||||
|
||||
void _openAccountCustomizer() {
|
||||
if (hasCustomize) {
|
||||
onCustomizeButtonTap();
|
||||
HapticFeedback.mediumImpact();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// The row, the hardware-wallet glyph and the inner accounts button are one
|
||||
// control for a screen reader: a single labeled node opening the customizer.
|
||||
final semanticsLabel =
|
||||
hardwareWalletType == null ? name : "$name, ${S.of(context).hardware_wallet}";
|
||||
|
||||
final row = GestureDetector(
|
||||
onTap: _openAccountCustomizer,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
AnimatedSwitcher(
|
||||
duration: Duration(milliseconds: 150),
|
||||
transitionBuilder: (child, animation) {
|
||||
return SizeTransition(
|
||||
return Semantics(
|
||||
label: semanticsLabel,
|
||||
child: ExcludeSemantics(
|
||||
child: Row(
|
||||
children: [
|
||||
AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 150),
|
||||
transitionBuilder: (child, animation) => SizeTransition(
|
||||
axis: Axis.horizontal,
|
||||
sizeFactor: animation,
|
||||
child: FadeTransition(opacity: animation, child: child),
|
||||
);
|
||||
},
|
||||
child: hardwareWalletIcon == null
|
||||
? const SizedBox.shrink(key: ValueKey("empty"))
|
||||
: Padding(
|
||||
padding: const EdgeInsets.only(right: 8),
|
||||
child: CakeImageWidget(
|
||||
imageUrl: hardwareWalletIcon!,
|
||||
key: ValueKey("hardware_wallet_icon"),
|
||||
width: 24,
|
||||
height: 24,
|
||||
colorFilter: ColorFilter.mode(
|
||||
Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
child: hardwareWalletIcon == null
|
||||
? const SizedBox.shrink(key: ValueKey("empty"))
|
||||
: Padding(
|
||||
padding: const EdgeInsets.only(right: 4),
|
||||
child: CakeImageWidget(
|
||||
imageUrl: hardwareWalletIcon!,
|
||||
key: const ValueKey("hardware_wallet_icon"),
|
||||
width: 24,
|
||||
height: 24,
|
||||
colorFilter: ColorFilter.mode(
|
||||
Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
name,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.titleLarge
|
||||
?.copyWith(color: Theme.of(context).colorScheme.onSurface),
|
||||
),
|
||||
if (hasCustomize) ...[
|
||||
SizedBox(width: 8),
|
||||
ModernButton.svg(
|
||||
size: 24,
|
||||
onPressed: _openAccountCustomizer,
|
||||
svgPath: "assets/new-ui/icon-accounts.svg",
|
||||
semanticLabel: S.of(context).wallet_accounts,
|
||||
)
|
||||
]
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
name,
|
||||
maxLines: 1,
|
||||
softWrap: false,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.titleMedium
|
||||
?.copyWith(color: Theme.of(context).colorScheme.onSurface),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
if (!hasCustomize) {
|
||||
return Semantics(label: semanticsLabel, child: ExcludeSemantics(child: row));
|
||||
}
|
||||
|
||||
return Semantics(
|
||||
button: true,
|
||||
label: semanticsLabel,
|
||||
hint: S.of(context).wallet_accounts,
|
||||
onTap: _openAccountCustomizer,
|
||||
child: ExcludeSemantics(child: row),
|
||||
);
|
||||
}
|
||||
|
||||
String? get hardwareWalletIcon {
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:cake_wallet/anonpay/anonpay_invoice_info.dart';
|
||||
import "package:cake_wallet/core/auth_service.dart";
|
||||
import 'package:cake_wallet/core/new_wallet_arguments.dart';
|
||||
import 'package:cake_wallet/new-ui/new_dashboard.dart';
|
||||
import "package:cake_wallet/new-ui/pages/account_customizer.dart";
|
||||
import 'package:cake_wallet/new-ui/pages/about_page.dart';
|
||||
import 'package:cake_wallet/new-ui/pages/bridge/bridge_history_page.dart';
|
||||
import 'package:cake_wallet/new-ui/pages/bridge/bridge_network_page.dart';
|
||||
@@ -670,6 +671,13 @@ Route<dynamic> createRoute(RouteSettings settings) {
|
||||
builder: (_) => getIt.get<MoneroAccountEditOrCreatePage>(
|
||||
param1: settings.arguments as AccountListItem?));
|
||||
|
||||
case Routes.accountCustomizer:
|
||||
return handleRouteWithPlatformAwareness(
|
||||
(_) => getIt.get<AccountCustomizer>(
|
||||
param1: settings.arguments! as DashboardViewModel,
|
||||
),
|
||||
);
|
||||
|
||||
case Routes.nanoAccountCreation:
|
||||
return CupertinoPageRoute<String>(
|
||||
builder: (_) =>
|
||||
|
||||
@@ -32,6 +32,7 @@ class Routes {
|
||||
static const login = '/login';
|
||||
static const splash = '/splash';
|
||||
static const accountCreation = '/account_new';
|
||||
static const accountCustomizer = "/account_customizer";
|
||||
static const nanoAccountCreation = '/nano_account_new';
|
||||
static const addressBook = '/address_book';
|
||||
static const pickerAddressBook = '/picker_address_book';
|
||||
|
||||
Reference in New Issue
Block a user