mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-23 03:59:23 +00:00
CWA-220 | changed menu widget; changed primary account to primary subaddress in subaddress list; applied short address if the label of a subaddress is empty; applied full address when long press on subaddress tile without label; applied biometrical authentication button when the authentication switch is on; changed dismissible icon in the node list page
This commit is contained in:
parent
872dbeb8ac
commit
289d8dca42
7 changed files with 363 additions and 314 deletions
|
@ -8,6 +8,8 @@ import 'package:cake_wallet/src/stores/auth/auth_store.dart';
|
|||
import 'package:cake_wallet/src/screens/pin_code/pin_code.dart';
|
||||
import 'package:cake_wallet/src/stores/settings/settings_store.dart';
|
||||
import 'package:cake_wallet/src/domain/common/biometric_auth.dart';
|
||||
import 'package:cake_wallet/themes.dart';
|
||||
import 'package:cake_wallet/theme_changer.dart';
|
||||
|
||||
typedef OnAuthenticationFinished = void Function(bool, AuthPageState);
|
||||
|
||||
|
@ -26,6 +28,7 @@ class AuthPageState extends State<AuthPage> {
|
|||
final _pinCodeKey = GlobalKey<PinCodeState>();
|
||||
final _backArrowImageDarkTheme =
|
||||
Image.asset('assets/images/back_arrow_dark_theme.png');
|
||||
final _backArrowImage = Image.asset('assets/images/back_arrow.png');
|
||||
|
||||
void changeProcessText(String text) {
|
||||
_key.currentState.showSnackBar(
|
||||
|
@ -39,6 +42,10 @@ class AuthPageState extends State<AuthPage> {
|
|||
final authStore = Provider.of<AuthStore>(context);
|
||||
final settingsStore = Provider.of<SettingsStore>(context);
|
||||
|
||||
final _themeChanger = Provider.of<ThemeChanger>(context);
|
||||
final _backButton = _themeChanger.getTheme() == Themes.darkTheme
|
||||
? _backArrowImageDarkTheme : _backArrowImage;
|
||||
|
||||
if (settingsStore.allowBiometricalAuthentication) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
final biometricAuth = BiometricAuth();
|
||||
|
@ -134,7 +141,7 @@ class AuthPageState extends State<AuthPage> {
|
|||
splashColor: Colors.transparent,
|
||||
padding: EdgeInsets.all(0),
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
child: _backArrowImageDarkTheme),
|
||||
child: _backButton),
|
||||
),
|
||||
)
|
||||
: Container(),
|
||||
|
@ -146,6 +153,7 @@ class AuthPageState extends State<AuthPage> {
|
|||
(pin, _) => authStore.auth(
|
||||
password: pin.fold('', (ac, val) => ac + '$val')),
|
||||
false,
|
||||
_pinCodeKey));
|
||||
_pinCodeKey,
|
||||
authStore: authStore,));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ class DashboardPageBodyState extends State<DashboardPageBody> {
|
|||
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
endDrawer: MenuWidget(),
|
||||
body: Container(
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
|
@ -49,17 +50,16 @@ class DashboardPageBodyState extends State<DashboardPageBody> {
|
|||
width: 44,
|
||||
child: ButtonTheme(
|
||||
minWidth: double.minPositive,
|
||||
child: FlatButton(
|
||||
highlightColor: Colors.transparent,
|
||||
splashColor: Colors.transparent,
|
||||
padding: EdgeInsets.all(0),
|
||||
onPressed: () async {
|
||||
await showDialog<void>(
|
||||
builder: (_) => MenuWidget(),
|
||||
context: context
|
||||
);
|
||||
},
|
||||
child: menuButton),
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
return FlatButton(
|
||||
highlightColor: Colors.transparent,
|
||||
splashColor: Colors.transparent,
|
||||
padding: EdgeInsets.all(0),
|
||||
onPressed: () => Scaffold.of(context).openEndDrawer(),
|
||||
child: menuButton);
|
||||
}
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import 'dart:async';
|
||||
import 'dart:ui';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/wallet_menu.dart';
|
||||
import 'package:cake_wallet/src/stores/wallet/wallet_store.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
@ -19,7 +17,6 @@ class MenuWidgetState extends State<MenuWidget> {
|
|||
double screenWidth;
|
||||
double screenHeight;
|
||||
double opacity;
|
||||
bool isDraw;
|
||||
|
||||
double headerHeight;
|
||||
double tileHeight;
|
||||
|
@ -32,7 +29,6 @@ class MenuWidgetState extends State<MenuWidget> {
|
|||
screenWidth = 0;
|
||||
screenHeight = 0;
|
||||
opacity = 0;
|
||||
isDraw = false;
|
||||
|
||||
headerHeight = 120;
|
||||
tileHeight = 75;
|
||||
|
@ -59,10 +55,6 @@ class MenuWidgetState extends State<MenuWidget> {
|
|||
fromBottomEdge *= scale;
|
||||
}
|
||||
});
|
||||
|
||||
Timer(Duration(milliseconds: 350), () =>
|
||||
setState(() => isDraw = true)
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -71,194 +63,174 @@ class MenuWidgetState extends State<MenuWidget> {
|
|||
final walletStore = Provider.of<WalletStore>(context);
|
||||
final itemCount = walletMenu.items.length;
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () => Navigator.of(context).pop(),
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
child: BackdropFilter(
|
||||
filter: ImageFilter.blur(sigmaX: 3.0, sigmaY: 3.0),
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 24),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(color: PaletteDark.darkNightBlue.withOpacity(0.75)),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 24),
|
||||
child: isDraw
|
||||
? Container(
|
||||
height: 60,
|
||||
width: 4,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(2)),
|
||||
color: Theme.of(context).hintColor //
|
||||
),
|
||||
)
|
||||
: Container(
|
||||
height: 60,
|
||||
width: 4,
|
||||
)
|
||||
),
|
||||
SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: () => null,
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
alignment: Alignment.centerRight,
|
||||
child: AnimatedContainer(
|
||||
alignment: Alignment.centerLeft,
|
||||
width: menuWidth,
|
||||
height: double.infinity,
|
||||
duration: Duration(milliseconds: 500),
|
||||
curve: Curves.fastOutSlowIn,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.only(topLeft: Radius.circular(24), bottomLeft: Radius.circular(24)),
|
||||
color: Theme.of(context).primaryTextTheme.display1.color.withOpacity(opacity)
|
||||
),
|
||||
child: isDraw
|
||||
? ListView.separated(
|
||||
itemBuilder: (_, index) {
|
||||
|
||||
if (index == 0) {
|
||||
return Container(
|
||||
height: headerHeight,
|
||||
padding: EdgeInsets.only(
|
||||
left: 24,
|
||||
top: fromTopEdge,
|
||||
right: 24,
|
||||
bottom: fromBottomEdge),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.only(topLeft: Radius.circular(24)),
|
||||
color: Theme.of(context).primaryTextTheme.display2.color
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
moneroIcon,
|
||||
SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: Container(
|
||||
height: 40,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
walletStore.name,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).primaryTextTheme.title.color,
|
||||
decoration: TextDecoration.none,
|
||||
fontFamily: 'Lato',
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold
|
||||
),
|
||||
),
|
||||
Text(
|
||||
walletStore.account.label,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).primaryTextTheme.caption.color,
|
||||
decoration: TextDecoration.none,
|
||||
fontFamily: 'Lato',
|
||||
fontSize: 12
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
index -= 1;
|
||||
final item = walletMenu.items[index];
|
||||
final image = walletMenu.images[index] ?? Offstage();
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.of(context).pop();
|
||||
walletMenu.action(index);
|
||||
},
|
||||
child: index == itemCount - 1
|
||||
? Container(
|
||||
height: headerHeight,
|
||||
padding: EdgeInsets.only(
|
||||
left: 24,
|
||||
right: 24,
|
||||
top: fromBottomEdge,
|
||||
bottom: fromTopEdge),
|
||||
alignment: Alignment.topLeft,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.only(bottomLeft: Radius.circular(24)),
|
||||
color: Theme.of(context).primaryTextTheme.display1.color,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
image,
|
||||
SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: Text(
|
||||
item,
|
||||
style: TextStyle(
|
||||
decoration: TextDecoration.none,
|
||||
color: Theme.of(context).primaryTextTheme.title.color,
|
||||
fontFamily: 'Lato',
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold
|
||||
),
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
: Container(
|
||||
height: tileHeight,
|
||||
padding: EdgeInsets.only(left: 24, right: 24),
|
||||
color: Theme.of(context).primaryTextTheme.display1.color,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
image,
|
||||
SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: Text(
|
||||
item,
|
||||
style: TextStyle(
|
||||
decoration: TextDecoration.none,
|
||||
color: Theme.of(context).primaryTextTheme.title.color,
|
||||
fontFamily: 'Lato',
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold
|
||||
),
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
separatorBuilder: (_, index) =>
|
||||
Container(
|
||||
height: 1,
|
||||
color: Theme.of(context).dividerColor,
|
||||
),
|
||||
itemCount: itemCount + 1)
|
||||
: Offstage()
|
||||
),
|
||||
),
|
||||
)
|
||||
)
|
||||
],
|
||||
)
|
||||
),
|
||||
height: 60,
|
||||
width: 4,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(2)),
|
||||
color: Theme.of(context).hintColor
|
||||
),
|
||||
)
|
||||
),
|
||||
),
|
||||
SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: () => null,
|
||||
child: Container(
|
||||
width: menuWidth,
|
||||
height: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(24),
|
||||
bottomLeft: Radius.circular(24)),
|
||||
color: Theme.of(context).primaryTextTheme.display1.color
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(24),
|
||||
bottomLeft: Radius.circular(24)),
|
||||
child: ListView.separated(
|
||||
itemBuilder: (_, index) {
|
||||
|
||||
if (index == 0) {
|
||||
return Container(
|
||||
height: headerHeight,
|
||||
padding: EdgeInsets.only(
|
||||
left: 24,
|
||||
top: fromTopEdge,
|
||||
right: 24,
|
||||
bottom: fromBottomEdge),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.only(topLeft: Radius.circular(24)),
|
||||
color: Theme.of(context).primaryTextTheme.display2.color
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
moneroIcon,
|
||||
SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: Container(
|
||||
height: 40,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
walletStore.name,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).primaryTextTheme.title.color,
|
||||
decoration: TextDecoration.none,
|
||||
fontFamily: 'Lato',
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold
|
||||
),
|
||||
),
|
||||
Text(
|
||||
walletStore.account.label,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).primaryTextTheme.caption.color,
|
||||
decoration: TextDecoration.none,
|
||||
fontFamily: 'Lato',
|
||||
fontSize: 12
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
index -= 1;
|
||||
final item = walletMenu.items[index];
|
||||
final image = walletMenu.images[index] ?? Offstage();
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.of(context).pop();
|
||||
walletMenu.action(index);
|
||||
},
|
||||
child: index == itemCount - 1
|
||||
? Container(
|
||||
height: headerHeight,
|
||||
padding: EdgeInsets.only(
|
||||
left: 24,
|
||||
right: 24,
|
||||
top: fromBottomEdge,
|
||||
bottom: fromTopEdge),
|
||||
alignment: Alignment.topLeft,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.only(bottomLeft: Radius.circular(24)),
|
||||
color: Theme.of(context).primaryTextTheme.display1.color,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
image,
|
||||
SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: Text(
|
||||
item,
|
||||
style: TextStyle(
|
||||
decoration: TextDecoration.none,
|
||||
color: Theme.of(context).primaryTextTheme.title.color,
|
||||
fontFamily: 'Lato',
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold
|
||||
),
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
: Container(
|
||||
height: tileHeight,
|
||||
padding: EdgeInsets.only(left: 24, right: 24),
|
||||
color: Theme.of(context).primaryTextTheme.display1.color,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
image,
|
||||
SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: Text(
|
||||
item,
|
||||
style: TextStyle(
|
||||
decoration: TextDecoration.none,
|
||||
color: Theme.of(context).primaryTextTheme.title.color,
|
||||
fontFamily: 'Lato',
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold
|
||||
),
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
separatorBuilder: (_, index) =>
|
||||
Container(
|
||||
height: 1,
|
||||
color: Theme.of(context).dividerColor,
|
||||
),
|
||||
itemCount: itemCount + 1),
|
||||
),
|
||||
),
|
||||
)
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
|
@ -77,8 +77,6 @@ class NodeListPageBodyState extends State<NodeListPageBody> {
|
|||
final nodeList = Provider.of<NodeListStore>(context);
|
||||
final settings = Provider.of<SettingsStore>(context);
|
||||
|
||||
final trashImage = Image.asset('assets/images/trash.png', height: 32, width: 32, color: Colors.white);
|
||||
|
||||
final currentColor = Theme.of(context).accentTextTheme.subtitle.decorationColor;
|
||||
final notCurrentColor = Theme.of(context).accentTextTheme.title.backgroundColor;
|
||||
|
||||
|
@ -194,12 +192,16 @@ class NodeListPageBodyState extends State<NodeListPageBody> {
|
|||
await nodeList.remove(node: node),
|
||||
direction: DismissDirection.endToStart,
|
||||
background: Container(
|
||||
padding: EdgeInsets.only(right: 10.0, top: 2),
|
||||
padding: EdgeInsets.only(right: 10.0),
|
||||
alignment: AlignmentDirectional.centerEnd,
|
||||
color: Palette.red,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
trashImage,
|
||||
const Icon(
|
||||
CupertinoIcons.delete,
|
||||
color: Colors.white,
|
||||
),
|
||||
Text(
|
||||
S.of(context).delete,
|
||||
style: TextStyle(color: Colors.white),
|
||||
|
|
|
@ -3,6 +3,8 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:cake_wallet/src/stores/settings/settings_store.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/src/stores/auth/auth_store.dart';
|
||||
import 'package:cake_wallet/src/domain/common/biometric_auth.dart';
|
||||
|
||||
abstract class PinCodeWidget extends StatefulWidget {
|
||||
PinCodeWidget({Key key, this.onPinCodeEntered, this.hasLengthSwitcher})
|
||||
|
@ -14,21 +16,26 @@ abstract class PinCodeWidget extends StatefulWidget {
|
|||
|
||||
class PinCode extends PinCodeWidget {
|
||||
PinCode(Function(List<int> pin, PinCodeState state) onPinCodeEntered,
|
||||
bool hasLengthSwitcher, Key key)
|
||||
bool hasLengthSwitcher, Key key, {this.authStore})
|
||||
: super(
|
||||
key: key,
|
||||
onPinCodeEntered: onPinCodeEntered,
|
||||
hasLengthSwitcher: hasLengthSwitcher);
|
||||
|
||||
final AuthStore authStore;
|
||||
|
||||
@override
|
||||
PinCodeState createState() => PinCodeState();
|
||||
PinCodeState createState() => PinCodeState(authStore: authStore);
|
||||
}
|
||||
|
||||
class PinCodeState<T extends PinCodeWidget> extends State<T> {
|
||||
PinCodeState({this.authStore});
|
||||
static const defaultPinLength = 4;
|
||||
static const sixPinLength = 6;
|
||||
static const fourPinLength = 4;
|
||||
final _gridViewKey = GlobalKey();
|
||||
final AuthStore authStore;
|
||||
final _key = GlobalKey<ScaffoldState>();
|
||||
|
||||
int pinLength = defaultPinLength;
|
||||
List<int> pin = List<int>.filled(defaultPinLength, null);
|
||||
|
@ -83,9 +90,11 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
|
|||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => Scaffold(body: body(context));
|
||||
Widget build(BuildContext context) => Scaffold(key: _key, body: body(context));
|
||||
|
||||
Widget body(BuildContext context) {
|
||||
final settingsStore = Provider.of<SettingsStore>(context);
|
||||
|
||||
final deleteIconImage = Image.asset(
|
||||
'assets/images/delete_icon.png',
|
||||
color: Theme.of(context).primaryTextTheme.title.color,
|
||||
|
@ -161,10 +170,35 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
|
|||
margin: EdgeInsets.only(
|
||||
left: marginLeft, right: marginRight),
|
||||
child: FlatButton(
|
||||
onPressed: () {},
|
||||
onPressed: (widget.hasLengthSwitcher ||
|
||||
!settingsStore.allowBiometricalAuthentication)
|
||||
? null
|
||||
: () {
|
||||
if (authStore != null) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
final biometricAuth = BiometricAuth();
|
||||
biometricAuth.isAuthenticated().then(
|
||||
(isAuth) {
|
||||
if (isAuth) {
|
||||
authStore.biometricAuth();
|
||||
_key.currentState.showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(S.of(context).authenticated),
|
||||
backgroundColor: Colors.green,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
color: Theme.of(context).backgroundColor,
|
||||
shape: CircleBorder(),
|
||||
child: faceImage,
|
||||
child: (widget.hasLengthSwitcher ||
|
||||
!settingsStore.allowBiometricalAuthentication)
|
||||
? Offstage()
|
||||
: faceImage,
|
||||
),
|
||||
);
|
||||
} else if (index == 10) {
|
||||
|
|
|
@ -245,110 +245,130 @@ class ReceivePageState extends State<ReceivePage> {
|
|||
),
|
||||
),
|
||||
Observer(
|
||||
builder: (_) => ListView.separated(
|
||||
separatorBuilder: (context, index) => Divider(
|
||||
height: 1,
|
||||
color: Theme.of(context).dividerColor,
|
||||
),
|
||||
shrinkWrap: true,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
itemCount: subaddressListStore.subaddresses.length + 2,
|
||||
itemBuilder: (context, index) {
|
||||
builder: (_) {
|
||||
subaddressListStore.updateShortAddressShow();
|
||||
|
||||
if (index == 0) {
|
||||
return ClipRRect(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(24),
|
||||
topRight: Radius.circular(24)
|
||||
),
|
||||
child: HeaderTile(
|
||||
onTap: () async {
|
||||
await showDialog<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AccountListPage(accountListStore: accountListStore);
|
||||
}
|
||||
);
|
||||
},
|
||||
title: walletStore.account.label,
|
||||
return ListView.separated(
|
||||
separatorBuilder: (context, index) => Divider(
|
||||
height: 1,
|
||||
color: Theme.of(context).dividerColor,
|
||||
),
|
||||
shrinkWrap: true,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
itemCount: subaddressListStore.subaddresses.length + 2,
|
||||
itemBuilder: (context, index) {
|
||||
|
||||
if (index == 0) {
|
||||
return ClipRRect(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(24),
|
||||
topRight: Radius.circular(24)
|
||||
),
|
||||
child: HeaderTile(
|
||||
onTap: () async {
|
||||
await showDialog<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AccountListPage(accountListStore: accountListStore);
|
||||
}
|
||||
);
|
||||
},
|
||||
title: walletStore.account.label,
|
||||
icon: Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
size: 14,
|
||||
color: Theme.of(context).primaryTextTheme.title.color,
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if (index == 1) {
|
||||
return HeaderTile(
|
||||
onTap: () => Navigator.of(context)
|
||||
.pushNamed(Routes.newSubaddress),
|
||||
title: S.of(context).subaddresses,
|
||||
icon: Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
size: 14,
|
||||
Icons.add,
|
||||
size: 20,
|
||||
color: Theme.of(context).primaryTextTheme.title.color,
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
index -= 2;
|
||||
|
||||
return Observer(
|
||||
builder: (_) {
|
||||
final subaddress = subaddressListStore.subaddresses[index];
|
||||
final isCurrent =
|
||||
walletStore.subaddress.address == subaddress.address;
|
||||
|
||||
String shortAddress = subaddress.address;
|
||||
shortAddress = shortAddress.replaceRange(8, shortAddress.length - 8, '...');
|
||||
|
||||
final content = Observer(
|
||||
builder: (_) {
|
||||
final isShortAddressShow = subaddressListStore.isShortAddressShow[index];
|
||||
|
||||
final label = index == 0
|
||||
? 'Primary subaddress'
|
||||
: subaddress.label.isNotEmpty
|
||||
? subaddress.label
|
||||
: isShortAddressShow ? shortAddress : subaddress.address;
|
||||
|
||||
return InkWell(
|
||||
onTap: () => walletStore.setSubaddress(subaddress),
|
||||
onLongPress: () {
|
||||
if (subaddress.label.isNotEmpty) {
|
||||
return;
|
||||
}
|
||||
subaddressListStore.setShortAddressShow(index, !isShortAddressShow);
|
||||
},
|
||||
child: Container(
|
||||
color: isCurrent ? currentColor : notCurrentColor,
|
||||
padding: EdgeInsets.only(
|
||||
left: 24,
|
||||
right: 24,
|
||||
top: 28,
|
||||
bottom: 28
|
||||
),
|
||||
child: Text(
|
||||
label,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: isCurrent
|
||||
? currentTextColor
|
||||
: notCurrentTextColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
return isCurrent || index == 0
|
||||
? content
|
||||
: Slidable(
|
||||
key: Key(subaddress.address),
|
||||
actionPane: SlidableDrawerActionPane(),
|
||||
child: content,
|
||||
secondaryActions: <Widget>[
|
||||
IconSlideAction(
|
||||
caption: S.of(context).edit,
|
||||
color: Theme.of(context).primaryTextTheme.overline.color,
|
||||
icon: Icons.edit,
|
||||
onTap: () => Navigator.of(context)
|
||||
.pushNamed(Routes.newSubaddress, arguments: subaddress),
|
||||
)
|
||||
]
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (index == 1) {
|
||||
return HeaderTile(
|
||||
onTap: () => Navigator.of(context)
|
||||
.pushNamed(Routes.newSubaddress),
|
||||
title: S.of(context).subaddresses,
|
||||
icon: Icon(
|
||||
Icons.add,
|
||||
size: 20,
|
||||
color: Theme.of(context).primaryTextTheme.title.color,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
index -= 2;
|
||||
|
||||
return Observer(
|
||||
builder: (_) {
|
||||
final subaddress = subaddressListStore.subaddresses[index];
|
||||
final isCurrent =
|
||||
walletStore.subaddress.address == subaddress.address;
|
||||
|
||||
final label = subaddress.label.isNotEmpty
|
||||
? subaddress.label
|
||||
: subaddress.address;
|
||||
|
||||
final content = InkWell(
|
||||
onTap: () => walletStore.setSubaddress(subaddress),
|
||||
child: Container(
|
||||
color: isCurrent ? currentColor : notCurrentColor,
|
||||
padding: EdgeInsets.only(
|
||||
left: 24,
|
||||
right: 24,
|
||||
top: 28,
|
||||
bottom: 28
|
||||
),
|
||||
child: Text(
|
||||
label,
|
||||
style: TextStyle(
|
||||
fontSize: subaddress.label.isNotEmpty
|
||||
? 18 : 10,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: isCurrent
|
||||
? currentTextColor
|
||||
: notCurrentTextColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return isCurrent
|
||||
? content
|
||||
: Slidable(
|
||||
key: Key(subaddress.address),
|
||||
actionPane: SlidableDrawerActionPane(),
|
||||
child: content,
|
||||
secondaryActions: <Widget>[
|
||||
IconSlideAction(
|
||||
caption: S.of(context).edit,
|
||||
color: Theme.of(context).primaryTextTheme.overline.color,
|
||||
icon: Icons.edit,
|
||||
onTap: () => Navigator.of(context)
|
||||
.pushNamed(Routes.newSubaddress, arguments: subaddress),
|
||||
)
|
||||
]
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
@ -15,6 +15,7 @@ class SubaddressListStore = SubaddressListStoreBase with _$SubaddressListStore;
|
|||
abstract class SubaddressListStoreBase with Store {
|
||||
SubaddressListStoreBase({@required WalletService walletService}) {
|
||||
subaddresses = ObservableList<Subaddress>();
|
||||
isShortAddressShow = ObservableList<bool>();
|
||||
|
||||
if (walletService.currentWallet != null) {
|
||||
_onWalletChanged(walletService.currentWallet);
|
||||
|
@ -27,12 +28,20 @@ abstract class SubaddressListStoreBase with Store {
|
|||
@observable
|
||||
ObservableList<Subaddress> subaddresses;
|
||||
|
||||
@observable
|
||||
ObservableList<bool> isShortAddressShow;
|
||||
|
||||
SubaddressList _subaddressList;
|
||||
StreamSubscription<Wallet> _onWalletChangeSubscription;
|
||||
StreamSubscription<List<Subaddress>> _onSubaddressesChangeSubscription;
|
||||
StreamSubscription<Account> _onAccountChangeSubscription;
|
||||
Account _account;
|
||||
|
||||
@action
|
||||
void setShortAddressShow(int index, bool isShow) {
|
||||
isShortAddressShow[index] = isShow;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
if (_onSubaddressesChangeSubscription != null) {
|
||||
|
@ -47,6 +56,10 @@ abstract class SubaddressListStoreBase with Store {
|
|||
super.dispose();
|
||||
}
|
||||
|
||||
void updateShortAddressShow() {
|
||||
isShortAddressShow = ObservableList.of(List.generate(subaddresses.length, (i) => true));
|
||||
}
|
||||
|
||||
Future<void> _updateSubaddressList({int accountIndex}) async {
|
||||
await _subaddressList.refresh(accountIndex: accountIndex);
|
||||
subaddresses = ObservableList.of(_subaddressList.getAll());
|
||||
|
|
Loading…
Reference in a new issue