desktop tx search filter + various bugfixes

This commit is contained in:
julian 2022-10-27 16:04:13 -06:00
parent ec7840419f
commit cc0770b2a2
4 changed files with 772 additions and 536 deletions

View file

@ -306,7 +306,7 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> {
"Search",
searchFieldFocusNode,
context,
desktopMed: true,
desktopMed: isDesktop,
).copyWith(
prefixIcon: Padding(
padding: EdgeInsets.symmetric(
@ -330,6 +330,7 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> {
onTap: () async {
setState(() {
_searchController.text = "";
_searchString = "";
});
},
),
@ -342,11 +343,13 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> {
),
),
),
if (isDesktop)
const SizedBox(
width: 20,
),
if (isDesktop)
SecondaryButton(
desktopMed: true,
desktopMed: isDesktop,
width: 200,
label: "Filter",
icon: SvgPicture.asset(
@ -358,14 +361,26 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> {
height: 20,
),
onPressed: () {
Navigator.of(context).pushNamed(
TransactionSearchFilterView.routeName,
arguments: ref
final coin = ref
.read(walletsChangeNotifierProvider)
.getManager(walletId)
.coin,
.coin;
if (isDesktop) {
showDialog<void>(
context: context,
builder: (context) {
return TransactionSearchFilterView(
coin: coin,
);
},
);
} else {
Navigator.of(context).pushNamed(
TransactionSearchFilterView.routeName,
arguments: coin,
);
}
},
),
],
),
@ -402,6 +417,7 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> {
final monthlyList = groupTransactionsByMonth(searched);
return ListView.builder(
primary: isDesktop ? false : null,
itemCount: monthlyList.length,
itemBuilder: (_, index) {
final month = monthlyList[index];

View file

@ -16,6 +16,10 @@ import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
import 'package:stackwallet/widgets/desktop/primary_button.dart';
import 'package:stackwallet/widgets/desktop/secondary_button.dart';
import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
import 'package:stackwallet/widgets/stack_text_field.dart';
@ -43,6 +47,7 @@ class _TransactionSearchViewState
bool _isActiveReceivedCheckbox = false;
bool _isActiveSentCheckbox = false;
bool _isActiveTradeCheckbox = false;
String _fromDateString = "";
String _toDateString = "";
@ -63,6 +68,9 @@ class _TransactionSearchViewState
_selectedFromDate = filterState.from;
_keywordTextEditingController.text = filterState.keyword;
_fromDateString = Format.formatDate(_selectedFromDate);
_toDateString = Format.formatDate(_selectedToDate);
// TODO: Fix XMR (modify Format.funcs to take optional Coin parameter)
// final amt = Format.satoshisToAmount(widget.coin == Coin.monero ? )
String amount = "";
@ -166,7 +174,11 @@ class _TransactionSearchViewState
Widget _buildDateRangePicker() {
const middleSeparatorPadding = 2.0;
const middleSeparatorWidth = 12.0;
final width = (MediaQuery.of(context).size.width -
final isDesktop = Util.isDesktop;
final width = isDesktop
? null
: (MediaQuery.of(context).size.width -
(middleSeparatorWidth +
(2 * middleSeparatorPadding) +
(2 * Constants.size.standardPadding))) /
@ -175,7 +187,8 @@ class _TransactionSearchViewState
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
Expanded(
child: GestureDetector(
key: const Key("transactionSearchViewFromDatePickerKey"),
onTap: () async {
final color =
@ -243,7 +256,10 @@ class _TransactionSearchViewState
),
),
child: Padding(
padding: const EdgeInsets.all(12),
padding: EdgeInsets.symmetric(
horizontal: 12,
vertical: isDesktop ? 17 : 12,
),
child: Row(
children: [
SvgPicture.asset(
@ -268,6 +284,7 @@ class _TransactionSearchViewState
),
),
),
),
Padding(
padding:
const EdgeInsets.symmetric(horizontal: middleSeparatorPadding),
@ -277,7 +294,8 @@ class _TransactionSearchViewState
// color: CFColors.smoke,
),
),
GestureDetector(
Expanded(
child: GestureDetector(
key: const Key("transactionSearchViewToDatePickerKey"),
onTap: () async {
final color =
@ -345,7 +363,10 @@ class _TransactionSearchViewState
),
),
child: Padding(
padding: const EdgeInsets.all(12),
padding: EdgeInsets.symmetric(
horizontal: 12,
vertical: isDesktop ? 17 : 12,
),
child: Row(
children: [
SvgPicture.asset(
@ -370,16 +391,35 @@ class _TransactionSearchViewState
),
),
),
),
if (isDesktop)
const SizedBox(
width: 24,
),
],
);
}
@override
Widget build(BuildContext context) {
if (Util.isDesktop) {
return DesktopDialog(
maxWidth: 576,
maxHeight: double.infinity,
child: Padding(
padding: const EdgeInsets.only(
left: 32,
bottom: 32,
),
child: _buildContent(context),
),
);
} else {
return Scaffold(
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
appBar: AppBar(
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
backgroundColor:
Theme.of(context).extension<StackColors>()!.background,
leading: AppBarBackButton(
onPressed: () async {
if (FocusScope.of(context).hasFocus) {
@ -406,11 +446,38 @@ class _TransactionSearchViewState
child: ConstrainedBox(
constraints: BoxConstraints(minHeight: constraints.maxHeight),
child: IntrinsicHeight(
child: Column(
children: [
const SizedBox(
height: 10,
child: _buildContent(context),
),
),
);
},
),
),
);
}
}
Widget _buildContent(BuildContext context) {
final isDesktop = Util.isDesktop;
return Column(
children: [
if (isDesktop)
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Transaction filter",
style: STextStyles.desktopH3(context),
textAlign: TextAlign.center,
),
const DesktopDialogCloseButton(),
],
),
SizedBox(
height: isDesktop ? 14 : 10,
),
if (!isDesktop)
Align(
alignment: Alignment.centerLeft,
child: FittedBox(
@ -420,10 +487,12 @@ class _TransactionSearchViewState
),
),
),
if (!isDesktop)
const SizedBox(
height: 12,
),
RoundedWhiteContainer(
padding: EdgeInsets.all(isDesktop ? 0 : 12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@ -432,8 +501,7 @@ class _TransactionSearchViewState
GestureDetector(
onTap: () {
setState(() {
_isActiveSentCheckbox =
!_isActiveSentCheckbox;
_isActiveSentCheckbox = !_isActiveSentCheckbox;
});
},
child: Container(
@ -447,13 +515,11 @@ class _TransactionSearchViewState
key: const Key(
"transactionSearchViewSentCheckboxKey"),
materialTapTargetSize:
MaterialTapTargetSize
.shrinkWrap,
MaterialTapTargetSize.shrinkWrap,
value: _isActiveSentCheckbox,
onChanged: (newValue) {
setState(() {
_isActiveSentCheckbox =
newValue!;
_isActiveSentCheckbox = newValue!;
});
},
),
@ -464,10 +530,19 @@ class _TransactionSearchViewState
Align(
alignment: Alignment.centerLeft,
child: FittedBox(
child: Text(
child: Column(
children: [
Text(
"Sent",
style: STextStyles.itemSubtitle12(
context),
style: isDesktop
? STextStyles.desktopTextSmall(context)
: STextStyles.itemSubtitle12(context),
),
if (isDesktop)
const SizedBox(
height: 4,
),
],
),
),
)
@ -477,16 +552,15 @@ class _TransactionSearchViewState
),
],
),
const SizedBox(
height: 10,
SizedBox(
height: isDesktop ? 4 : 10,
),
Row(
children: [
GestureDetector(
onTap: () {
setState(() {
_isActiveReceivedCheckbox =
!_isActiveReceivedCheckbox;
_isActiveReceivedCheckbox = !_isActiveReceivedCheckbox;
});
},
child: Container(
@ -500,13 +574,11 @@ class _TransactionSearchViewState
key: const Key(
"transactionSearchViewReceivedCheckboxKey"),
materialTapTargetSize:
MaterialTapTargetSize
.shrinkWrap,
MaterialTapTargetSize.shrinkWrap,
value: _isActiveReceivedCheckbox,
onChanged: (newValue) {
setState(() {
_isActiveReceivedCheckbox =
newValue!;
_isActiveReceivedCheckbox = newValue!;
});
},
),
@ -517,10 +589,78 @@ class _TransactionSearchViewState
Align(
alignment: Alignment.centerLeft,
child: FittedBox(
child: Text(
child: Column(
children: [
Text(
"Received",
style: STextStyles.itemSubtitle12(
context),
style: isDesktop
? STextStyles.desktopTextSmall(context)
: STextStyles.itemSubtitle12(context),
),
if (isDesktop)
const SizedBox(
height: 4,
),
],
),
),
)
],
),
),
),
],
),
SizedBox(
height: isDesktop ? 4 : 10,
),
Row(
children: [
GestureDetector(
onTap: () {
setState(() {
_isActiveTradeCheckbox = !_isActiveTradeCheckbox;
});
},
child: Container(
color: Colors.transparent,
child: Row(
children: [
SizedBox(
height: 20,
width: 20,
child: Checkbox(
key: const Key(
"transactionSearchViewSentCheckboxKey"),
materialTapTargetSize:
MaterialTapTargetSize.shrinkWrap,
value: _isActiveTradeCheckbox,
onChanged: (newValue) {
setState(() {
_isActiveTradeCheckbox = newValue!;
});
},
),
),
const SizedBox(
width: 14,
),
Align(
alignment: Alignment.centerLeft,
child: FittedBox(
child: Column(
children: [
Text(
"Trades",
style: isDesktop
? STextStyles.desktopTextSmall(context)
: STextStyles.itemSubtitle12(context),
),
if (isDesktop)
const SizedBox(
height: 4,
),
],
),
),
)
@ -533,38 +673,44 @@ class _TransactionSearchViewState
],
),
),
const SizedBox(
height: 24,
SizedBox(
height: isDesktop ? 32 : 24,
),
Align(
alignment: Alignment.centerLeft,
child: FittedBox(
child: Text(
"Date",
style: STextStyles.smallMed12(context),
style: isDesktop
? STextStyles.labelExtraExtraSmall(context)
: STextStyles.smallMed12(context),
),
),
),
const SizedBox(
height: 8,
SizedBox(
height: isDesktop ? 10 : 8,
),
_buildDateRangePicker(),
const SizedBox(
height: 24,
SizedBox(
height: isDesktop ? 32 : 24,
),
Align(
alignment: Alignment.centerLeft,
child: FittedBox(
child: Text(
"Amount",
style: STextStyles.smallMed12(context),
style: isDesktop
? STextStyles.labelExtraExtraSmall(context)
: STextStyles.smallMed12(context),
),
),
),
const SizedBox(
height: 8,
SizedBox(
height: isDesktop ? 10 : 8,
),
ClipRRect(
Padding(
padding: EdgeInsets.only(right: isDesktop ? 32 : 0),
child: ClipRRect(
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
@ -581,21 +727,32 @@ class _TransactionSearchViewState
),
inputFormatters: [
// regex to validate a crypto amount with 8 decimal places
TextInputFormatter.withFunction((oldValue,
newValue) =>
TextInputFormatter.withFunction((oldValue, newValue) =>
RegExp(r'^([0-9]*[,.]?[0-9]{0,8}|[,.][0-9]{0,8})$')
.hasMatch(newValue.text)
? newValue
: oldValue),
],
style: STextStyles.field(context),
style: isDesktop
? STextStyles.desktopTextExtraSmall(context).copyWith(
color:
Theme.of(context).extension<StackColors>()!.textDark,
height: 1.8,
)
: STextStyles.field(context),
decoration: standardInputDecoration(
"Enter ${widget.coin.ticker} amount...",
keywordTextFieldFocusNode,
context,
desktopMed: isDesktop,
).copyWith(
suffixIcon: _amountTextEditingController
.text.isNotEmpty
contentPadding: isDesktop
? const EdgeInsets.symmetric(
vertical: 10,
horizontal: 16,
)
: null,
suffixIcon: _amountTextEditingController.text.isNotEmpty
? Padding(
padding: const EdgeInsets.only(right: 0),
child: UnconstrainedBox(
@ -605,8 +762,7 @@ class _TransactionSearchViewState
child: const XIcon(),
onTap: () async {
setState(() {
_amountTextEditingController
.text = "";
_amountTextEditingController.text = "";
});
},
),
@ -618,41 +774,57 @@ class _TransactionSearchViewState
),
),
),
const SizedBox(
height: 24,
),
SizedBox(
height: isDesktop ? 32 : 24,
),
Align(
alignment: Alignment.centerLeft,
child: FittedBox(
child: Text(
"Keyword",
style: STextStyles.smallMed12(context),
style: isDesktop
? STextStyles.labelExtraExtraSmall(context)
: STextStyles.smallMed12(context),
),
),
),
const SizedBox(
height: 8,
SizedBox(
height: isDesktop ? 10 : 8,
),
ClipRRect(
Padding(
padding: EdgeInsets.only(right: isDesktop ? 32 : 0),
child: ClipRRect(
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
child: TextField(
autocorrect: Util.isDesktop ? false : true,
enableSuggestions: Util.isDesktop ? false : true,
key:
const Key("transactionSearchViewKeywordFieldKey"),
key: const Key("transactionSearchViewKeywordFieldKey"),
controller: _keywordTextEditingController,
focusNode: keywordTextFieldFocusNode,
style: STextStyles.field(context),
style: isDesktop
? STextStyles.desktopTextExtraSmall(context).copyWith(
color:
Theme.of(context).extension<StackColors>()!.textDark,
height: 1.8,
)
: STextStyles.field(context),
onChanged: (_) => setState(() {}),
decoration: standardInputDecoration(
"Type keyword...",
keywordTextFieldFocusNode,
context,
desktopMed: isDesktop,
).copyWith(
suffixIcon: _keywordTextEditingController
.text.isNotEmpty
contentPadding: isDesktop
? const EdgeInsets.symmetric(
vertical: 10,
horizontal: 16,
)
: null,
suffixIcon: _keywordTextEditingController.text.isNotEmpty
? Padding(
padding: const EdgeInsets.only(right: 0),
child: UnconstrainedBox(
@ -662,8 +834,7 @@ class _TransactionSearchViewState
child: const XIcon(),
onTap: () async {
setState(() {
_keywordTextEditingController
.text = "";
_keywordTextEditingController.text = "";
});
},
),
@ -675,72 +846,101 @@ class _TransactionSearchViewState
),
),
),
const Spacer(),
const SizedBox(
height: 20,
),
if (!isDesktop) const Spacer(),
SizedBox(
height: isDesktop ? 32 : 20,
),
Row(
children: [
Expanded(
child: SizedBox(
height: 48,
child: TextButton(
child: SecondaryButton(
label: "Cancel",
desktopMed: isDesktop,
onPressed: () async {
if (!isDesktop) {
if (FocusScope.of(context).hasFocus) {
FocusScope.of(context).unfocus();
await Future<void>.delayed(
const Duration(milliseconds: 75));
const Duration(
milliseconds: 75,
),
);
}
}
if (mounted) {
Navigator.of(context).pop();
}
},
style: Theme.of(context)
.extension<StackColors>()!
.getSecondaryEnabledButtonColor(context),
child: Text(
"Cancel",
style: STextStyles.button(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark),
),
),
),
),
// Expanded(
// child: SizedBox(
// height: 48,
// child: TextButton(
// onPressed: () async {
// if (FocusScope.of(context).hasFocus) {
// FocusScope.of(context).unfocus();
// await Future<void>.delayed(
// const Duration(milliseconds: 75));
// }
// if (mounted) {
// Navigator.of(context).pop();
// }
// },
// style: Theme.of(context)
// .extension<StackColors>()!
// .getSecondaryEnabledButtonColor(context),
// child: Text(
// "Cancel",
// style: STextStyles.button(context).copyWith(
// color: Theme.of(context)
// .extension<StackColors>()!
// .accentColorDark),
// ),
// ),
// ),
// ),
const SizedBox(
width: 16,
),
Expanded(
child: SizedBox(
height: 48,
child: TextButton(
style: Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context),
child: PrimaryButton(
desktopMed: isDesktop,
onPressed: () async {
_onApplyPressed();
await _onApplyPressed();
},
child: Text(
"Save",
style: STextStyles.button(context),
),
label: "Save",
),
),
// Expanded(
// child: SizedBox(
// height: 48,
// child: TextButton(
// style: Theme.of(context)
// .extension<StackColors>()!
// .getPrimaryEnabledButtonColor(context),
// onPressed: () async {
// await _onApplyPressed();
// },
// child: Text(
// "Save",
// style: STextStyles.button(context),
// ),
// ),
// ),
// ),
if (isDesktop)
const SizedBox(
width: 32,
),
],
),
if (!isDesktop)
const SizedBox(
height: 20,
),
],
),
),
),
);
},
),
),
);
}

View file

@ -359,6 +359,7 @@ class _MyWalletState extends State<MyWallet> {
@override
Widget build(BuildContext context) {
return ListView(
primary: false,
children: [
Text(
"My wallet",

View file

@ -228,6 +228,25 @@ class STextStyles {
}
}
static TextStyle labelExtraExtraSmall(BuildContext context) {
switch (_theme(context).themeType) {
case ThemeType.light:
return GoogleFonts.inter(
color: _theme(context).textFieldActiveSearchIconRight,
fontWeight: FontWeight.w500,
fontSize: 14,
height: 14 / 14,
);
case ThemeType.dark:
return GoogleFonts.inter(
color: _theme(context).textFieldActiveSearchIconRight,
fontWeight: FontWeight.w500,
fontSize: 14,
height: 14 / 14,
);
}
}
static TextStyle label700(BuildContext context) {
switch (_theme(context).themeType) {
case ThemeType.light: