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
Oleksandr Sobol committed
Jun 5, 2020 at 12:34 UTC
289d8dca428626d40d428c7d53df99d1fa57bb9c
7 files changed
+357
-308
lib/src/screens/auth/auth_page.dart
+10
-2
@@ -8,6 +8,8 @@ import 'package:cake_wallet/src/stores/auth/auth_store.dart';
8
import 'package:cake_wallet/src/screens/pin_code/pin_code.dart';
9
import 'package:cake_wallet/src/stores/settings/settings_store.dart';
10
import 'package:cake_wallet/src/domain/common/biometric_auth.dart';
11
+import 'package:cake_wallet/themes.dart';
12
+import 'package:cake_wallet/theme_changer.dart';
13
14
typedef OnAuthenticationFinished = void Function(bool, AuthPageState);
15
@@ -26,6 +28,7 @@ class AuthPageState extends State<AuthPage> {
28
final _pinCodeKey = GlobalKey<PinCodeState>();
29
final _backArrowImageDarkTheme =
30
Image.asset('assets/images/back_arrow_dark_theme.png');
31
+ final _backArrowImage = Image.asset('assets/images/back_arrow.png');
32
33
void changeProcessText(String text) {
34
_key.currentState.showSnackBar(
@@ -39,6 +42,10 @@ class AuthPageState extends State<AuthPage> {
42
final authStore = Provider.of<AuthStore>(context);
43
final settingsStore = Provider.of<SettingsStore>(context);
44
45
+ final _themeChanger = Provider.of<ThemeChanger>(context);
46
+ final _backButton = _themeChanger.getTheme() == Themes.darkTheme
47
+ ? _backArrowImageDarkTheme : _backArrowImage;
48
+
49
if (settingsStore.allowBiometricalAuthentication) {
50
WidgetsBinding.instance.addPostFrameCallback((_) {
51
final biometricAuth = BiometricAuth();
@@ -134,7 +141,7 @@ class AuthPageState extends State<AuthPage> {
141
splashColor: Colors.transparent,
142
padding: EdgeInsets.all(0),
143
onPressed: () => Navigator.of(context).pop(),
137
- child: _backArrowImageDarkTheme),
144
+ child: _backButton),
145
),
146
)
147
: Container(),
@@ -146,6 +153,7 @@ class AuthPageState extends State<AuthPage> {
153
(pin, _) => authStore.auth(
154
password: pin.fold('', (ac, val) => ac + '$val')),
155
false,
149
- _pinCodeKey));
156
+ _pinCodeKey,
157
+ authStore: authStore,));
158
}
159
}
lib/src/screens/dashboard/dashboard_page.dart
+11
-11
@@ -28,6 +28,7 @@ class DashboardPageBodyState extends State<DashboardPageBody> {
28
29
return SafeArea(
30
child: Scaffold(
31
+ endDrawer: MenuWidget(),
32
body: Container(
33
decoration: BoxDecoration(
34
gradient: LinearGradient(
@@ -49,17 +50,16 @@ class DashboardPageBodyState extends State<DashboardPageBody> {
50
width: 44,
51
child: ButtonTheme(
52
minWidth: double.minPositive,
52
- child: FlatButton(
53
- highlightColor: Colors.transparent,
54
- splashColor: Colors.transparent,
55
- padding: EdgeInsets.all(0),
56
- onPressed: () async {
57
- await showDialog<void>(
58
- builder: (_) => MenuWidget(),
59
- context: context
60
- );
61
- },
62
- child: menuButton),
53
+ child: Builder(
54
+ builder: (context) {
55
+ return FlatButton(
56
+ highlightColor: Colors.transparent,
57
+ splashColor: Colors.transparent,
58
+ padding: EdgeInsets.all(0),
59
+ onPressed: () => Scaffold.of(context).openEndDrawer(),
60
+ child: menuButton);
61
+ }
62
+ ),
63
),
64
),
65
),
lib/src/screens/dashboard/widgets/menu_widget.dart
+164
-192
@@ -1,7 +1,5 @@
1
-import 'dart:async';
1
import 'dart:ui';
2
import 'package:flutter/material.dart';
4
-import 'package:cake_wallet/palette.dart';
3
import 'package:cake_wallet/src/screens/dashboard/wallet_menu.dart';
4
import 'package:cake_wallet/src/stores/wallet/wallet_store.dart';
5
import 'package:provider/provider.dart';
@@ -19,7 +17,6 @@ class MenuWidgetState extends State<MenuWidget> {
17
double screenWidth;
18
double screenHeight;
19
double opacity;
22
- bool isDraw;
20
21
double headerHeight;
22
double tileHeight;
@@ -32,7 +29,6 @@ class MenuWidgetState extends State<MenuWidget> {
29
screenWidth = 0;
30
screenHeight = 0;
31
opacity = 0;
35
- isDraw = false;
32
33
headerHeight = 120;
34
tileHeight = 75;
@@ -59,10 +55,6 @@ class MenuWidgetState extends State<MenuWidget> {
55
fromBottomEdge *= scale;
56
}
57
});
62
-
63
- Timer(Duration(milliseconds: 350), () =>
64
- setState(() => isDraw = true)
65
- );
58
}
59
60
@override
@@ -71,194 +63,174 @@ class MenuWidgetState extends State<MenuWidget> {
63
final walletStore = Provider.of<WalletStore>(context);
64
final itemCount = walletMenu.items.length;
65
74
- return GestureDetector(
75
- onTap: () => Navigator.of(context).pop(),
76
- child: Container(
77
- color: Colors.transparent,
78
- child: BackdropFilter(
79
- filter: ImageFilter.blur(sigmaX: 3.0, sigmaY: 3.0),
66
+ return Row(
67
+ mainAxisSize: MainAxisSize.max,
68
+ crossAxisAlignment: CrossAxisAlignment.center,
69
+ children: <Widget>[
70
+ Padding(
71
+ padding: EdgeInsets.only(left: 24),
72
child: Container(
81
- decoration: BoxDecoration(color: PaletteDark.darkNightBlue.withOpacity(0.75)),
82
- child: Row(
83
- mainAxisSize: MainAxisSize.max,
84
- crossAxisAlignment: CrossAxisAlignment.center,
85
- children: <Widget>[
86
- Padding(
87
- padding: EdgeInsets.only(left: 24),
88
- child: isDraw
89
- ? Container(
90
- height: 60,
91
- width: 4,
92
- decoration: BoxDecoration(
93
- borderRadius: BorderRadius.all(Radius.circular(2)),
94
- color: Theme.of(context).hintColor //
95
- ),
96
- )
97
- : Container(
98
- height: 60,
99
- width: 4,
100
- )
73
+ height: 60,
74
+ width: 4,
75
+ decoration: BoxDecoration(
76
+ borderRadius: BorderRadius.all(Radius.circular(2)),
77
+ color: Theme.of(context).hintColor
78
+ ),
79
+ )
80
+ ),
81
+ SizedBox(width: 12),
82
+ Expanded(
83
+ child: GestureDetector(
84
+ onTap: () => null,
85
+ child: Container(
86
+ width: menuWidth,
87
+ height: double.infinity,
88
+ decoration: BoxDecoration(
89
+ borderRadius: BorderRadius.only(
90
+ topLeft: Radius.circular(24),
91
+ bottomLeft: Radius.circular(24)),
92
+ color: Theme.of(context).primaryTextTheme.display1.color
93
),
102
- SizedBox(width: 12),
103
- Expanded(
104
- child: GestureDetector(
105
- onTap: () => null,
106
- child: Container(
107
- width: double.infinity,
108
- height: double.infinity,
109
- alignment: Alignment.centerRight,
110
- child: AnimatedContainer(
111
- alignment: Alignment.centerLeft,
112
- width: menuWidth,
113
- height: double.infinity,
114
- duration: Duration(milliseconds: 500),
115
- curve: Curves.fastOutSlowIn,
116
- decoration: BoxDecoration(
117
- borderRadius: BorderRadius.only(topLeft: Radius.circular(24), bottomLeft: Radius.circular(24)),
118
- color: Theme.of(context).primaryTextTheme.display1.color.withOpacity(opacity)
94
+ child: ClipRRect(
95
+ borderRadius: BorderRadius.only(
96
+ topLeft: Radius.circular(24),
97
+ bottomLeft: Radius.circular(24)),
98
+ child: ListView.separated(
99
+ itemBuilder: (_, index) {
100
+
101
+ if (index == 0) {
102
+ return Container(
103
+ height: headerHeight,
104
+ padding: EdgeInsets.only(
105
+ left: 24,
106
+ top: fromTopEdge,
107
+ right: 24,
108
+ bottom: fromBottomEdge),
109
+ decoration: BoxDecoration(
110
+ borderRadius: BorderRadius.only(topLeft: Radius.circular(24)),
111
+ color: Theme.of(context).primaryTextTheme.display2.color
112
+ ),
113
+ child: Row(
114
+ mainAxisAlignment: MainAxisAlignment.start,
115
+ children: <Widget>[
116
+ moneroIcon,
117
+ SizedBox(width: 16),
118
+ Expanded(
119
+ child: Container(
120
+ height: 40,
121
+ child: Column(
122
+ crossAxisAlignment: CrossAxisAlignment.start,
123
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
124
+ children: <Widget>[
125
+ Text(
126
+ walletStore.name,
127
+ style: TextStyle(
128
+ color: Theme.of(context).primaryTextTheme.title.color,
129
+ decoration: TextDecoration.none,
130
+ fontFamily: 'Lato',
131
+ fontSize: 20,
132
+ fontWeight: FontWeight.bold
133
+ ),
134
+ ),
135
+ Text(
136
+ walletStore.account.label,
137
+ style: TextStyle(
138
+ color: Theme.of(context).primaryTextTheme.caption.color,
139
+ decoration: TextDecoration.none,
140
+ fontFamily: 'Lato',
141
+ fontSize: 12
142
+ ),
143
+ )
144
+ ],
145
+ ),
146
+ )
147
+ )
148
+ ],
149
+ ),
150
+ );
151
+ }
152
+
153
+ index -= 1;
154
+ final item = walletMenu.items[index];
155
+ final image = walletMenu.images[index] ?? Offstage();
156
+
157
+ return GestureDetector(
158
+ onTap: () {
159
+ Navigator.of(context).pop();
160
+ walletMenu.action(index);
161
+ },
162
+ child: index == itemCount - 1
163
+ ? Container(
164
+ height: headerHeight,
165
+ padding: EdgeInsets.only(
166
+ left: 24,
167
+ right: 24,
168
+ top: fromBottomEdge,
169
+ bottom: fromTopEdge),
170
+ alignment: Alignment.topLeft,
171
+ decoration: BoxDecoration(
172
+ borderRadius: BorderRadius.only(bottomLeft: Radius.circular(24)),
173
+ color: Theme.of(context).primaryTextTheme.display1.color,
174
+ ),
175
+ child: Row(
176
+ mainAxisAlignment: MainAxisAlignment.start,
177
+ crossAxisAlignment: CrossAxisAlignment.center,
178
+ children: <Widget>[
179
+ image,
180
+ SizedBox(width: 16),
181
+ Expanded(
182
+ child: Text(
183
+ item,
184
+ style: TextStyle(
185
+ decoration: TextDecoration.none,
186
+ color: Theme.of(context).primaryTextTheme.title.color,
187
+ fontFamily: 'Lato',
188
+ fontSize: 20,
189
+ fontWeight: FontWeight.bold
190
+ ),
191
+ )
192
+ )
193
+ ],
194
+ ),
195
+ )
196
+ : Container(
197
+ height: tileHeight,
198
+ padding: EdgeInsets.only(left: 24, right: 24),
199
+ color: Theme.of(context).primaryTextTheme.display1.color,
200
+ child: Row(
201
+ mainAxisAlignment: MainAxisAlignment.start,
202
+ crossAxisAlignment: CrossAxisAlignment.center,
203
+ children: <Widget>[
204
+ image,
205
+ SizedBox(width: 16),
206
+ Expanded(
207
+ child: Text(
208
+ item,
209
+ style: TextStyle(
210
+ decoration: TextDecoration.none,
211
+ color: Theme.of(context).primaryTextTheme.title.color,
212
+ fontFamily: 'Lato',
213
+ fontSize: 20,
214
+ fontWeight: FontWeight.bold
215
+ ),
216
+ )
217
+ )
218
+ ],
219
+ ),
220
),
120
- child: isDraw
121
- ? ListView.separated(
122
- itemBuilder: (_, index) {
123
-
124
- if (index == 0) {
125
- return Container(
126
- height: headerHeight,
127
- padding: EdgeInsets.only(
128
- left: 24,
129
- top: fromTopEdge,
130
- right: 24,
131
- bottom: fromBottomEdge),
132
- decoration: BoxDecoration(
133
- borderRadius: BorderRadius.only(topLeft: Radius.circular(24)),
134
- color: Theme.of(context).primaryTextTheme.display2.color
135
- ),
136
- child: Row(
137
- mainAxisAlignment: MainAxisAlignment.start,
138
- children: <Widget>[
139
- moneroIcon,
140
- SizedBox(width: 16),
141
- Expanded(
142
- child: Container(
143
- height: 40,
144
- child: Column(
145
- crossAxisAlignment: CrossAxisAlignment.start,
146
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
147
- children: <Widget>[
148
- Text(
149
- walletStore.name,
150
- style: TextStyle(
151
- color: Theme.of(context).primaryTextTheme.title.color,
152
- decoration: TextDecoration.none,
153
- fontFamily: 'Lato',
154
- fontSize: 20,
155
- fontWeight: FontWeight.bold
156
- ),
157
- ),
158
- Text(
159
- walletStore.account.label,
160
- style: TextStyle(
161
- color: Theme.of(context).primaryTextTheme.caption.color,
162
- decoration: TextDecoration.none,
163
- fontFamily: 'Lato',
164
- fontSize: 12
165
- ),
166
- )
167
- ],
168
- ),
169
- )
170
- )
171
- ],
172
- ),
173
- );
174
- }
175
-
176
- index -= 1;
177
- final item = walletMenu.items[index];
178
- final image = walletMenu.images[index] ?? Offstage();
179
-
180
- return GestureDetector(
181
- onTap: () {
182
- Navigator.of(context).pop();
183
- walletMenu.action(index);
184
- },
185
- child: index == itemCount - 1
186
- ? Container(
187
- height: headerHeight,
188
- padding: EdgeInsets.only(
189
- left: 24,
190
- right: 24,
191
- top: fromBottomEdge,
192
- bottom: fromTopEdge),
193
- alignment: Alignment.topLeft,
194
- decoration: BoxDecoration(
195
- borderRadius: BorderRadius.only(bottomLeft: Radius.circular(24)),
196
- color: Theme.of(context).primaryTextTheme.display1.color,
197
- ),
198
- child: Row(
199
- mainAxisAlignment: MainAxisAlignment.start,
200
- crossAxisAlignment: CrossAxisAlignment.center,
201
- children: <Widget>[
202
- image,
203
- SizedBox(width: 16),
204
- Expanded(
205
- child: Text(
206
- item,
207
- style: TextStyle(
208
- decoration: TextDecoration.none,
209
- color: Theme.of(context).primaryTextTheme.title.color,
210
- fontFamily: 'Lato',
211
- fontSize: 20,
212
- fontWeight: FontWeight.bold
213
- ),
214
- )
215
- )
216
- ],
217
- ),
218
- )
219
- : Container(
220
- height: tileHeight,
221
- padding: EdgeInsets.only(left: 24, right: 24),
222
- color: Theme.of(context).primaryTextTheme.display1.color,
223
- child: Row(
224
- mainAxisAlignment: MainAxisAlignment.start,
225
- crossAxisAlignment: CrossAxisAlignment.center,
226
- children: <Widget>[
227
- image,
228
- SizedBox(width: 16),
229
- Expanded(
230
- child: Text(
231
- item,
232
- style: TextStyle(
233
- decoration: TextDecoration.none,
234
- color: Theme.of(context).primaryTextTheme.title.color,
235
- fontFamily: 'Lato',
236
- fontSize: 20,
237
- fontWeight: FontWeight.bold
238
- ),
239
- )
240
- )
241
- ],
242
- ),
243
- ),
244
- );
245
- },
246
- separatorBuilder: (_, index) =>
247
- Container(
248
- height: 1,
249
- color: Theme.of(context).dividerColor,
250
- ),
251
- itemCount: itemCount + 1)
252
- : Offstage()
253
- ),
254
- ),
255
- )
256
- )
257
- ],
221
+ );
222
+ },
223
+ separatorBuilder: (_, index) =>
224
+ Container(
225
+ height: 1,
226
+ color: Theme.of(context).dividerColor,
227
+ ),
228
+ itemCount: itemCount + 1),
229
+ ),
230
+ ),
231
)
259
- ),
260
- ),
261
- ),
232
+ )
233
+ ],
234
);
235
}
236
}
\ No newline at end of file
lib/src/screens/nodes/nodes_list_page.dart
+6
-4
@@ -77,8 +77,6 @@ class NodeListPageBodyState extends State<NodeListPageBody> {
77
final nodeList = Provider.of<NodeListStore>(context);
78
final settings = Provider.of<SettingsStore>(context);
79
80
- final trashImage = Image.asset('assets/images/trash.png', height: 32, width: 32, color: Colors.white);
81
-
80
final currentColor = Theme.of(context).accentTextTheme.subtitle.decorationColor;
81
final notCurrentColor = Theme.of(context).accentTextTheme.title.backgroundColor;
82
@@ -194,12 +192,16 @@ class NodeListPageBodyState extends State<NodeListPageBody> {
192
await nodeList.remove(node: node),
193
direction: DismissDirection.endToStart,
194
background: Container(
197
- padding: EdgeInsets.only(right: 10.0, top: 2),
195
+ padding: EdgeInsets.only(right: 10.0),
196
alignment: AlignmentDirectional.centerEnd,
197
color: Palette.red,
198
child: Column(
199
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
200
children: <Widget>[
202
- trashImage,
201
+ const Icon(
202
+ CupertinoIcons.delete,
203
+ color: Colors.white,
204
+ ),
205
Text(
206
S.of(context).delete,
207
style: TextStyle(color: Colors.white),
lib/src/screens/pin_code/pin_code.dart
+39
-5
@@ -3,6 +3,8 @@ import 'package:flutter/material.dart';
3
import 'package:flutter/cupertino.dart';
4
import 'package:cake_wallet/src/stores/settings/settings_store.dart';
5
import 'package:cake_wallet/generated/i18n.dart';
6
+import 'package:cake_wallet/src/stores/auth/auth_store.dart';
7
+import 'package:cake_wallet/src/domain/common/biometric_auth.dart';
8
9
abstract class PinCodeWidget extends StatefulWidget {
10
PinCodeWidget({Key key, this.onPinCodeEntered, this.hasLengthSwitcher})
@@ -14,21 +16,26 @@ abstract class PinCodeWidget extends StatefulWidget {
16
17
class PinCode extends PinCodeWidget {
18
PinCode(Function(List<int> pin, PinCodeState state) onPinCodeEntered,
17
- bool hasLengthSwitcher, Key key)
19
+ bool hasLengthSwitcher, Key key, {this.authStore})
20
: super(
21
key: key,
22
onPinCodeEntered: onPinCodeEntered,
23
hasLengthSwitcher: hasLengthSwitcher);
24
25
+ final AuthStore authStore;
26
+
27
@override
24
- PinCodeState createState() => PinCodeState();
28
+ PinCodeState createState() => PinCodeState(authStore: authStore);
29
}
30
31
class PinCodeState<T extends PinCodeWidget> extends State<T> {
32
+ PinCodeState({this.authStore});
33
static const defaultPinLength = 4;
34
static const sixPinLength = 6;
35
static const fourPinLength = 4;
36
final _gridViewKey = GlobalKey();
37
+ final AuthStore authStore;
38
+ final _key = GlobalKey<ScaffoldState>();
39
40
int pinLength = defaultPinLength;
41
List<int> pin = List<int>.filled(defaultPinLength, null);
@@ -83,9 +90,11 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
90
}
91
92
@override
86
- Widget build(BuildContext context) => Scaffold(body: body(context));
93
+ Widget build(BuildContext context) => Scaffold(key: _key, body: body(context));
94
95
Widget body(BuildContext context) {
96
+ final settingsStore = Provider.of<SettingsStore>(context);
97
+
98
final deleteIconImage = Image.asset(
99
'assets/images/delete_icon.png',
100
color: Theme.of(context).primaryTextTheme.title.color,
@@ -161,10 +170,35 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
170
margin: EdgeInsets.only(
171
left: marginLeft, right: marginRight),
172
child: FlatButton(
164
- onPressed: () {},
173
+ onPressed: (widget.hasLengthSwitcher ||
174
+ !settingsStore.allowBiometricalAuthentication)
175
+ ? null
176
+ : () {
177
+ if (authStore != null) {
178
+ WidgetsBinding.instance.addPostFrameCallback((_) {
179
+ final biometricAuth = BiometricAuth();
180
+ biometricAuth.isAuthenticated().then(
181
+ (isAuth) {
182
+ if (isAuth) {
183
+ authStore.biometricAuth();
184
+ _key.currentState.showSnackBar(
185
+ SnackBar(
186
+ content: Text(S.of(context).authenticated),
187
+ backgroundColor: Colors.green,
188
+ ),
189
+ );
190
+ }
191
+ }
192
+ );
193
+ });
194
+ }
195
+ },
196
color: Theme.of(context).backgroundColor,
197
shape: CircleBorder(),
167
- child: faceImage,
198
+ child: (widget.hasLengthSwitcher ||
199
+ !settingsStore.allowBiometricalAuthentication)
200
+ ? Offstage()
201
+ : faceImage,
202
),
203
);
204
} else if (index == 10) {
lib/src/screens/receive/receive_page.dart
+114
-94
@@ -245,110 +245,130 @@ class ReceivePageState extends State<ReceivePage> {
245
),
246
),
247
Observer(
248
- builder: (_) => ListView.separated(
249
- separatorBuilder: (context, index) => Divider(
250
- height: 1,
251
- color: Theme.of(context).dividerColor,
252
- ),
253
- shrinkWrap: true,
254
- physics: NeverScrollableScrollPhysics(),
255
- itemCount: subaddressListStore.subaddresses.length + 2,
256
- itemBuilder: (context, index) {
248
+ builder: (_) {
249
+ subaddressListStore.updateShortAddressShow();
250
258
- if (index == 0) {
259
- return ClipRRect(
260
- borderRadius: BorderRadius.only(
261
- topLeft: Radius.circular(24),
262
- topRight: Radius.circular(24)
263
- ),
264
- child: HeaderTile(
265
- onTap: () async {
266
- await showDialog<void>(
267
- context: context,
268
- builder: (BuildContext context) {
269
- return AccountListPage(accountListStore: accountListStore);
270
- }
271
- );
272
- },
273
- title: walletStore.account.label,
251
+ return ListView.separated(
252
+ separatorBuilder: (context, index) => Divider(
253
+ height: 1,
254
+ color: Theme.of(context).dividerColor,
255
+ ),
256
+ shrinkWrap: true,
257
+ physics: NeverScrollableScrollPhysics(),
258
+ itemCount: subaddressListStore.subaddresses.length + 2,
259
+ itemBuilder: (context, index) {
260
+
261
+ if (index == 0) {
262
+ return ClipRRect(
263
+ borderRadius: BorderRadius.only(
264
+ topLeft: Radius.circular(24),
265
+ topRight: Radius.circular(24)
266
+ ),
267
+ child: HeaderTile(
268
+ onTap: () async {
269
+ await showDialog<void>(
270
+ context: context,
271
+ builder: (BuildContext context) {
272
+ return AccountListPage(accountListStore: accountListStore);
273
+ }
274
+ );
275
+ },
276
+ title: walletStore.account.label,
277
+ icon: Icon(
278
+ Icons.arrow_forward_ios,
279
+ size: 14,
280
+ color: Theme.of(context).primaryTextTheme.title.color,
281
+ )
282
+ ),
283
+ );
284
+ }
285
+
286
+ if (index == 1) {
287
+ return HeaderTile(
288
+ onTap: () => Navigator.of(context)
289
+ .pushNamed(Routes.newSubaddress),
290
+ title: S.of(context).subaddresses,
291
icon: Icon(
275
- Icons.arrow_forward_ios,
276
- size: 14,
292
+ Icons.add,
293
+ size: 20,
294
color: Theme.of(context).primaryTextTheme.title.color,
295
)
279
- ),
280
- );
281
- }
296
+ );
297
+ }
298
283
- if (index == 1) {
284
- return HeaderTile(
285
- onTap: () => Navigator.of(context)
286
- .pushNamed(Routes.newSubaddress),
287
- title: S.of(context).subaddresses,
288
- icon: Icon(
289
- Icons.add,
290
- size: 20,
291
- color: Theme.of(context).primaryTextTheme.title.color,
292
- )
293
- );
294
- }
299
+ index -= 2;
300
296
- index -= 2;
301
+ return Observer(
302
+ builder: (_) {
303
+ final subaddress = subaddressListStore.subaddresses[index];
304
+ final isCurrent =
305
+ walletStore.subaddress.address == subaddress.address;
306
298
- return Observer(
299
- builder: (_) {
300
- final subaddress = subaddressListStore.subaddresses[index];
301
- final isCurrent =
302
- walletStore.subaddress.address == subaddress.address;
307
+ String shortAddress = subaddress.address;
308
+ shortAddress = shortAddress.replaceRange(8, shortAddress.length - 8, '...');
309
304
- final label = subaddress.label.isNotEmpty
305
- ? subaddress.label
306
- : subaddress.address;
310
+ final content = Observer(
311
+ builder: (_) {
312
+ final isShortAddressShow = subaddressListStore.isShortAddressShow[index];
313
308
- final content = InkWell(
309
- onTap: () => walletStore.setSubaddress(subaddress),
310
- child: Container(
311
- color: isCurrent ? currentColor : notCurrentColor,
312
- padding: EdgeInsets.only(
313
- left: 24,
314
- right: 24,
315
- top: 28,
316
- bottom: 28
317
- ),
318
- child: Text(
319
- label,
320
- style: TextStyle(
321
- fontSize: subaddress.label.isNotEmpty
322
- ? 18 : 10,
323
- fontWeight: FontWeight.bold,
324
- color: isCurrent
325
- ? currentTextColor
326
- : notCurrentTextColor,
327
- ),
328
- ),
329
- ),
330
- );
314
+ final label = index == 0
315
+ ? 'Primary subaddress'
316
+ : subaddress.label.isNotEmpty
317
+ ? subaddress.label
318
+ : isShortAddressShow ? shortAddress : subaddress.address;
319
+
320
+ return InkWell(
321
+ onTap: () => walletStore.setSubaddress(subaddress),
322
+ onLongPress: () {
323
+ if (subaddress.label.isNotEmpty) {
324
+ return;
325
+ }
326
+ subaddressListStore.setShortAddressShow(index, !isShortAddressShow);
327
+ },
328
+ child: Container(
329
+ color: isCurrent ? currentColor : notCurrentColor,
330
+ padding: EdgeInsets.only(
331
+ left: 24,
332
+ right: 24,
333
+ top: 28,
334
+ bottom: 28
335
+ ),
336
+ child: Text(
337
+ label,
338
+ style: TextStyle(
339
+ fontSize: 18,
340
+ fontWeight: FontWeight.bold,
341
+ color: isCurrent
342
+ ? currentTextColor
343
+ : notCurrentTextColor,
344
+ ),
345
+ ),
346
+ ),
347
+ );
348
+ }
349
+ );
350
332
- return isCurrent
333
- ? content
334
- : Slidable(
335
- key: Key(subaddress.address),
336
- actionPane: SlidableDrawerActionPane(),
337
- child: content,
338
- secondaryActions: <Widget>[
339
- IconSlideAction(
340
- caption: S.of(context).edit,
341
- color: Theme.of(context).primaryTextTheme.overline.color,
342
- icon: Icons.edit,
343
- onTap: () => Navigator.of(context)
344
- .pushNamed(Routes.newSubaddress, arguments: subaddress),
345
- )
346
- ]
347
- );
348
- }
349
- );
350
- }
351
- )
351
+ return isCurrent || index == 0
352
+ ? content
353
+ : Slidable(
354
+ key: Key(subaddress.address),
355
+ actionPane: SlidableDrawerActionPane(),
356
+ child: content,
357
+ secondaryActions: <Widget>[
358
+ IconSlideAction(
359
+ caption: S.of(context).edit,
360
+ color: Theme.of(context).primaryTextTheme.overline.color,
361
+ icon: Icons.edit,
362
+ onTap: () => Navigator.of(context)
363
+ .pushNamed(Routes.newSubaddress, arguments: subaddress),
364
+ )
365
+ ]
366
+ );
367
+ }
368
+ );
369
+ }
370
+ );
371
+ }
372
),
373
],
374
),
lib/src/stores/subaddress_list/subaddress_list_store.dart
+13
@@ -15,6 +15,7 @@ class SubaddressListStore = SubaddressListStoreBase with _$SubaddressListStore;
15
abstract class SubaddressListStoreBase with Store {
16
SubaddressListStoreBase({@required WalletService walletService}) {
17
subaddresses = ObservableList<Subaddress>();
18
+ isShortAddressShow = ObservableList<bool>();
19
20
if (walletService.currentWallet != null) {
21
_onWalletChanged(walletService.currentWallet);
@@ -27,12 +28,20 @@ abstract class SubaddressListStoreBase with Store {
28
@observable
29
ObservableList<Subaddress> subaddresses;
30
31
+ @observable
32
+ ObservableList<bool> isShortAddressShow;
33
+
34
SubaddressList _subaddressList;
35
StreamSubscription<Wallet> _onWalletChangeSubscription;
36
StreamSubscription<List<Subaddress>> _onSubaddressesChangeSubscription;
37
StreamSubscription<Account> _onAccountChangeSubscription;
38
Account _account;
39
40
+ @action
41
+ void setShortAddressShow(int index, bool isShow) {
42
+ isShortAddressShow[index] = isShow;
43
+ }
44
+
45
@override
46
void dispose() {
47
if (_onSubaddressesChangeSubscription != null) {
@@ -47,6 +56,10 @@ abstract class SubaddressListStoreBase with Store {
56
super.dispose();
57
}
58
59
+ void updateShortAddressShow() {
60
+ isShortAddressShow = ObservableList.of(List.generate(subaddresses.length, (i) => true));
61
+ }
62
+
63
Future<void> _updateSubaddressList({int accountIndex}) async {
64
await _subaddressList.refresh(accountIndex: accountIndex);
65
subaddresses = ObservableList.of(_subaddressList.getAll());