mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-11-17 09:47:37 +00:00
ordinals filter view
This commit is contained in:
parent
8b71fa70c9
commit
2af1a8db88
3 changed files with 901 additions and 4 deletions
|
@ -0,0 +1,890 @@
|
|||
/*
|
||||
* This file is part of Stack Wallet.
|
||||
*
|
||||
* Copyright (c) 2023 Cypher Stack
|
||||
* All Rights Reserved.
|
||||
* The code is distributed under GPLv3 license, see LICENSE file for details.
|
||||
* Generated by Cypher Stack on 2023-05-26
|
||||
*
|
||||
*/
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_rounded_date_picker/flutter_rounded_date_picker.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:stackwallet/themes/stack_colors.dart';
|
||||
import 'package:stackwallet/themes/theme_providers.dart';
|
||||
import 'package:stackwallet/utilities/assets.dart';
|
||||
import 'package:stackwallet/utilities/constants.dart';
|
||||
import 'package:stackwallet/utilities/format.dart';
|
||||
import 'package:stackwallet/utilities/text_styles.dart';
|
||||
import 'package:stackwallet/utilities/util.dart';
|
||||
import 'package:stackwallet/widgets/background.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';
|
||||
import 'package:stackwallet/widgets/textfield_icon_button.dart';
|
||||
|
||||
class OrdinalFilter {
|
||||
final bool isMoonbird;
|
||||
final bool isPunk;
|
||||
final DateTime? from;
|
||||
final DateTime? to;
|
||||
final String? inscription;
|
||||
final String keyword;
|
||||
|
||||
OrdinalFilter({
|
||||
required this.isMoonbird,
|
||||
required this.isPunk,
|
||||
required this.from,
|
||||
required this.to,
|
||||
required this.inscription,
|
||||
required this.keyword,
|
||||
});
|
||||
|
||||
OrdinalFilter copyWith({
|
||||
bool? isMoonbird,
|
||||
bool? isPunk,
|
||||
DateTime? from,
|
||||
DateTime? to,
|
||||
String? inscription,
|
||||
String? keyword,
|
||||
}) {
|
||||
return OrdinalFilter(
|
||||
isMoonbird: isMoonbird ?? this.isMoonbird,
|
||||
isPunk: isPunk ?? this.isPunk,
|
||||
from: from ?? this.from,
|
||||
to: to ?? this.to,
|
||||
inscription: inscription ?? this.inscription,
|
||||
keyword: keyword ?? this.keyword,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
final ordinalFilterProvider = StateProvider<OrdinalFilter?>((_) => null);
|
||||
|
||||
class OrdinalsFilterView extends ConsumerStatefulWidget {
|
||||
const OrdinalsFilterView({
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
static const String routeName = "/ordinalsFilterView";
|
||||
|
||||
@override
|
||||
ConsumerState<OrdinalsFilterView> createState() => _OrdinalsFilterViewState();
|
||||
}
|
||||
|
||||
class _OrdinalsFilterViewState extends ConsumerState<OrdinalsFilterView> {
|
||||
final _inscriptionTextEditingController = TextEditingController();
|
||||
final _keywordTextEditingController = TextEditingController();
|
||||
|
||||
bool _isPunk = false;
|
||||
bool _isMoonbird = false;
|
||||
|
||||
String _fromDateString = "";
|
||||
String _toDateString = "";
|
||||
|
||||
final keywordTextFieldFocusNode = FocusNode();
|
||||
final inscriptionTextFieldFocusNode = FocusNode();
|
||||
|
||||
late Color baseColor;
|
||||
|
||||
@override
|
||||
initState() {
|
||||
baseColor = ref.read(themeProvider.state).state.textSubtitle2;
|
||||
final filterState = ref.read(ordinalFilterProvider.state).state;
|
||||
if (filterState != null) {
|
||||
_isMoonbird = filterState.isMoonbird;
|
||||
_isPunk = filterState.isPunk;
|
||||
_selectedToDate = filterState.to;
|
||||
_selectedFromDate = filterState.from;
|
||||
_keywordTextEditingController.text = filterState.keyword;
|
||||
_inscriptionTextEditingController.text = filterState.inscription ?? "";
|
||||
}
|
||||
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
dispose() {
|
||||
_inscriptionTextEditingController.dispose();
|
||||
_keywordTextEditingController.dispose();
|
||||
keywordTextFieldFocusNode.dispose();
|
||||
inscriptionTextFieldFocusNode.dispose();
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
// The following two getters are not required if the
|
||||
// date fields are to remain unclearable.
|
||||
Widget get _dateFromText {
|
||||
final isDateSelected = _fromDateString.isEmpty;
|
||||
return Text(
|
||||
isDateSelected ? "From..." : _fromDateString,
|
||||
style: STextStyles.fieldLabel(context).copyWith(
|
||||
color: isDateSelected
|
||||
? Theme.of(context).extension<StackColors>()!.textSubtitle2
|
||||
: Theme.of(context).extension<StackColors>()!.accentColorDark),
|
||||
);
|
||||
}
|
||||
|
||||
Widget get _dateToText {
|
||||
final isDateSelected = _toDateString.isEmpty;
|
||||
return Text(
|
||||
isDateSelected ? "To..." : _toDateString,
|
||||
style: STextStyles.fieldLabel(context).copyWith(
|
||||
color: isDateSelected
|
||||
? Theme.of(context).extension<StackColors>()!.textSubtitle2
|
||||
: Theme.of(context).extension<StackColors>()!.accentColorDark),
|
||||
);
|
||||
}
|
||||
|
||||
DateTime? _selectedFromDate = DateTime(2007);
|
||||
DateTime? _selectedToDate = DateTime.now();
|
||||
|
||||
MaterialRoundedDatePickerStyle _buildDatePickerStyle() {
|
||||
return MaterialRoundedDatePickerStyle(
|
||||
backgroundPicker: Theme.of(context).extension<StackColors>()!.popupBG,
|
||||
// backgroundHeader: Theme.of(context).extension<StackColors>()!.textSubtitle2,
|
||||
paddingMonthHeader: const EdgeInsets.only(top: 11),
|
||||
colorArrowNext: Theme.of(context).extension<StackColors>()!.textSubtitle1,
|
||||
colorArrowPrevious:
|
||||
Theme.of(context).extension<StackColors>()!.textSubtitle1,
|
||||
textStyleButtonNegative: STextStyles.datePicker600(context).copyWith(
|
||||
color: baseColor,
|
||||
),
|
||||
textStyleButtonPositive: STextStyles.datePicker600(context).copyWith(
|
||||
color: baseColor,
|
||||
),
|
||||
textStyleCurrentDayOnCalendar: STextStyles.datePicker400(context),
|
||||
textStyleDayHeader: STextStyles.datePicker600(context),
|
||||
textStyleDayOnCalendar: STextStyles.datePicker400(context).copyWith(
|
||||
color: baseColor,
|
||||
),
|
||||
textStyleDayOnCalendarDisabled:
|
||||
STextStyles.datePicker400(context).copyWith(
|
||||
color: Theme.of(context).extension<StackColors>()!.textSubtitle3,
|
||||
),
|
||||
textStyleDayOnCalendarSelected:
|
||||
STextStyles.datePicker400(context).copyWith(
|
||||
color: Theme.of(context).extension<StackColors>()!.textWhite,
|
||||
),
|
||||
textStyleMonthYearHeader: STextStyles.datePicker600(context).copyWith(
|
||||
color: Theme.of(context).extension<StackColors>()!.textSubtitle1,
|
||||
),
|
||||
textStyleYearButton: STextStyles.datePicker600(context).copyWith(
|
||||
color: Theme.of(context).extension<StackColors>()!.textWhite,
|
||||
),
|
||||
// textStyleButtonAction: GoogleFonts.inter(),
|
||||
);
|
||||
}
|
||||
|
||||
MaterialRoundedYearPickerStyle _buildYearPickerStyle() {
|
||||
return MaterialRoundedYearPickerStyle(
|
||||
backgroundPicker: Theme.of(context).extension<StackColors>()!.popupBG,
|
||||
textStyleYear: STextStyles.datePicker600(context).copyWith(
|
||||
color: Theme.of(context).extension<StackColors>()!.textSubtitle2,
|
||||
fontSize: 16,
|
||||
),
|
||||
textStyleYearSelected: STextStyles.datePicker600(context).copyWith(
|
||||
fontSize: 18,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDateRangePicker() {
|
||||
const middleSeparatorPadding = 2.0;
|
||||
const middleSeparatorWidth = 12.0;
|
||||
final isDesktop = Util.isDesktop;
|
||||
|
||||
final width = isDesktop
|
||||
? null
|
||||
: (MediaQuery.of(context).size.width -
|
||||
(middleSeparatorWidth +
|
||||
(2 * middleSeparatorPadding) +
|
||||
(2 * Constants.size.standardPadding))) /
|
||||
2;
|
||||
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: GestureDetector(
|
||||
key: const Key("OrdinalsViewFromDatePickerKey"),
|
||||
onTap: () async {
|
||||
final color =
|
||||
Theme.of(context).extension<StackColors>()!.accentColorDark;
|
||||
final height = MediaQuery.of(context).size.height;
|
||||
// check and hide keyboard
|
||||
if (FocusScope.of(context).hasFocus) {
|
||||
FocusScope.of(context).unfocus();
|
||||
await Future<void>.delayed(const Duration(milliseconds: 125));
|
||||
}
|
||||
|
||||
if (mounted) {
|
||||
final date = await showRoundedDatePicker(
|
||||
// This doesn't change statusbar color...
|
||||
// background: CFColors.starryNight.withOpacity(0.8),
|
||||
context: context,
|
||||
initialDate: DateTime.now(),
|
||||
height: height * 0.5,
|
||||
theme: ThemeData(
|
||||
primarySwatch: Util.createMaterialColor(
|
||||
color,
|
||||
),
|
||||
),
|
||||
//TODO pick a better initial date
|
||||
// 2007 chosen as that is just before bitcoin launched
|
||||
firstDate: DateTime(2007),
|
||||
lastDate: DateTime.now(),
|
||||
borderRadius: Constants.size.circularBorderRadius * 2,
|
||||
|
||||
textPositiveButton: "SELECT",
|
||||
|
||||
styleDatePicker: _buildDatePickerStyle(),
|
||||
styleYearPicker: _buildYearPickerStyle(),
|
||||
);
|
||||
if (date != null) {
|
||||
_selectedFromDate = date;
|
||||
|
||||
// flag to adjust date so from date is always before to date
|
||||
final flag = _selectedToDate != null &&
|
||||
!_selectedFromDate!.isBefore(_selectedToDate!);
|
||||
if (flag) {
|
||||
_selectedToDate = DateTime.fromMillisecondsSinceEpoch(
|
||||
_selectedFromDate!.millisecondsSinceEpoch);
|
||||
}
|
||||
|
||||
setState(() {
|
||||
if (flag) {
|
||||
_toDateString = _selectedToDate == null
|
||||
? ""
|
||||
: Format.formatDate(_selectedToDate!);
|
||||
}
|
||||
_fromDateString = _selectedFromDate == null
|
||||
? ""
|
||||
: Format.formatDate(_selectedFromDate!);
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
width: width,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.textFieldDefaultBG,
|
||||
borderRadius:
|
||||
BorderRadius.circular(Constants.size.circularBorderRadius),
|
||||
border: Border.all(
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.textFieldDefaultBG,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 12,
|
||||
vertical: isDesktop ? 17 : 12,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
Assets.svg.calendar,
|
||||
height: 20,
|
||||
width: 20,
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.textSubtitle2,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: FittedBox(
|
||||
child: _dateFromText,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: middleSeparatorPadding),
|
||||
child: Container(
|
||||
width: middleSeparatorWidth,
|
||||
// height: 1,
|
||||
// color: CFColors.smoke,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: GestureDetector(
|
||||
key: const Key("OrdinalsViewToDatePickerKey"),
|
||||
onTap: () async {
|
||||
final color =
|
||||
Theme.of(context).extension<StackColors>()!.accentColorDark;
|
||||
final height = MediaQuery.of(context).size.height;
|
||||
// check and hide keyboard
|
||||
if (FocusScope.of(context).hasFocus) {
|
||||
FocusScope.of(context).unfocus();
|
||||
await Future<void>.delayed(const Duration(milliseconds: 125));
|
||||
}
|
||||
|
||||
if (mounted) {
|
||||
final date = await showRoundedDatePicker(
|
||||
// This doesn't change statusbar color...
|
||||
// background: CFColors.starryNight.withOpacity(0.8),
|
||||
context: context,
|
||||
height: height * 0.5,
|
||||
theme: ThemeData(
|
||||
primarySwatch: Util.createMaterialColor(
|
||||
color,
|
||||
),
|
||||
),
|
||||
//TODO pick a better initial date
|
||||
// 2007 chosen as that is just before bitcoin launched
|
||||
initialDate: DateTime.now(),
|
||||
firstDate: DateTime(2007),
|
||||
lastDate: DateTime.now(),
|
||||
borderRadius: Constants.size.circularBorderRadius * 2,
|
||||
|
||||
textPositiveButton: "SELECT",
|
||||
|
||||
styleDatePicker: _buildDatePickerStyle(),
|
||||
styleYearPicker: _buildYearPickerStyle(),
|
||||
);
|
||||
if (date != null) {
|
||||
_selectedToDate = date;
|
||||
|
||||
// flag to adjust date so from date is always before to date
|
||||
final flag = _selectedFromDate != null &&
|
||||
!_selectedToDate!.isAfter(_selectedFromDate!);
|
||||
if (flag) {
|
||||
_selectedFromDate = DateTime.fromMillisecondsSinceEpoch(
|
||||
_selectedToDate!.millisecondsSinceEpoch);
|
||||
}
|
||||
|
||||
setState(() {
|
||||
if (flag) {
|
||||
_fromDateString = _selectedFromDate == null
|
||||
? ""
|
||||
: Format.formatDate(_selectedFromDate!);
|
||||
}
|
||||
_toDateString = _selectedToDate == null
|
||||
? ""
|
||||
: Format.formatDate(_selectedToDate!);
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
width: width,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.textFieldDefaultBG,
|
||||
borderRadius:
|
||||
BorderRadius.circular(Constants.size.circularBorderRadius),
|
||||
border: Border.all(
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.textFieldDefaultBG,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 12,
|
||||
vertical: isDesktop ? 17 : 12,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
Assets.svg.calendar,
|
||||
height: 20,
|
||||
width: 20,
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.textSubtitle2,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: FittedBox(
|
||||
child: _dateToText,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
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 Background(
|
||||
child: Scaffold(
|
||||
backgroundColor:
|
||||
Theme.of(context).extension<StackColors>()!.background,
|
||||
appBar: AppBar(
|
||||
backgroundColor:
|
||||
Theme.of(context).extension<StackColors>()!.background,
|
||||
leading: AppBarBackButton(
|
||||
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();
|
||||
}
|
||||
},
|
||||
),
|
||||
title: Text(
|
||||
"Ordinals filter",
|
||||
style: STextStyles.navBarTitle(context),
|
||||
),
|
||||
),
|
||||
body: Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: Constants.size.standardPadding,
|
||||
),
|
||||
child: LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
return SingleChildScrollView(
|
||||
child: ConstrainedBox(
|
||||
constraints:
|
||||
BoxConstraints(minHeight: constraints.maxHeight),
|
||||
child: IntrinsicHeight(
|
||||
child: _buildContent(context),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildContent(BuildContext context) {
|
||||
final isDesktop = Util.isDesktop;
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
if (isDesktop)
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
"Ordinals filter",
|
||||
style: STextStyles.desktopH3(context),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const DesktopDialogCloseButton(),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: isDesktop ? 14 : 10,
|
||||
),
|
||||
if (!isDesktop)
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: FittedBox(
|
||||
child: Text(
|
||||
"Collection",
|
||||
style: STextStyles.smallMed12(context),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (!isDesktop)
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
RoundedWhiteContainer(
|
||||
padding: EdgeInsets.all(isDesktop ? 0 : 12),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_isPunk = !_isPunk;
|
||||
});
|
||||
},
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 20,
|
||||
width: 20,
|
||||
child: Checkbox(
|
||||
key: const Key("OrdinalsPunkCheckboxKey"),
|
||||
materialTapTargetSize:
|
||||
MaterialTapTargetSize.shrinkWrap,
|
||||
value: _isPunk,
|
||||
onChanged: (newValue) {
|
||||
setState(() {
|
||||
_isPunk = newValue!;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 14,
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: FittedBox(
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
"Punks",
|
||||
style: isDesktop
|
||||
? STextStyles.desktopTextSmall(context)
|
||||
: STextStyles.itemSubtitle12(context),
|
||||
),
|
||||
if (isDesktop)
|
||||
const SizedBox(
|
||||
height: 4,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: isDesktop ? 4 : 10,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_isMoonbird = !_isMoonbird;
|
||||
});
|
||||
},
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 20,
|
||||
width: 20,
|
||||
child: Checkbox(
|
||||
key: const Key(
|
||||
"OrdinalsFilterMoonbirdCheckboxKey",
|
||||
),
|
||||
materialTapTargetSize:
|
||||
MaterialTapTargetSize.shrinkWrap,
|
||||
value: _isMoonbird,
|
||||
onChanged: (newValue) {
|
||||
setState(() {
|
||||
_isMoonbird = newValue!;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 14,
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: FittedBox(
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
"Moonbirds",
|
||||
style: isDesktop
|
||||
? STextStyles.desktopTextSmall(context)
|
||||
: STextStyles.itemSubtitle12(context),
|
||||
),
|
||||
if (isDesktop)
|
||||
const SizedBox(
|
||||
height: 4,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: isDesktop ? 32 : 24,
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: FittedBox(
|
||||
child: Text(
|
||||
"Date",
|
||||
style: isDesktop
|
||||
? STextStyles.labelExtraExtraSmall(context)
|
||||
: STextStyles.smallMed12(context),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: isDesktop ? 10 : 8,
|
||||
),
|
||||
_buildDateRangePicker(),
|
||||
SizedBox(
|
||||
height: isDesktop ? 32 : 24,
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: FittedBox(
|
||||
child: Text(
|
||||
"Inscription",
|
||||
style: isDesktop
|
||||
? STextStyles.labelExtraExtraSmall(context)
|
||||
: STextStyles.smallMed12(context),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: isDesktop ? 10 : 8,
|
||||
),
|
||||
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("OrdinalsInscriptionFieldKey"),
|
||||
controller: _inscriptionTextEditingController,
|
||||
focusNode: inscriptionTextFieldFocusNode,
|
||||
onChanged: (_) => setState(() {}),
|
||||
style: isDesktop
|
||||
? STextStyles.desktopTextExtraSmall(context).copyWith(
|
||||
color:
|
||||
Theme.of(context).extension<StackColors>()!.textDark,
|
||||
height: 1.8,
|
||||
)
|
||||
: STextStyles.field(context),
|
||||
decoration: standardInputDecoration(
|
||||
"Enter inscription number...",
|
||||
keywordTextFieldFocusNode,
|
||||
context,
|
||||
desktopMed: isDesktop,
|
||||
).copyWith(
|
||||
contentPadding: isDesktop
|
||||
? const EdgeInsets.symmetric(
|
||||
vertical: 10,
|
||||
horizontal: 16,
|
||||
)
|
||||
: null,
|
||||
suffixIcon: _inscriptionTextEditingController.text.isNotEmpty
|
||||
? Padding(
|
||||
padding: const EdgeInsets.only(right: 0),
|
||||
child: UnconstrainedBox(
|
||||
child: Row(
|
||||
children: [
|
||||
TextFieldIconButton(
|
||||
child: const XIcon(),
|
||||
onTap: () async {
|
||||
setState(() {
|
||||
_inscriptionTextEditingController.text = "";
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
: null,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: isDesktop ? 32 : 24,
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: FittedBox(
|
||||
child: Text(
|
||||
"Keyword",
|
||||
style: isDesktop
|
||||
? STextStyles.labelExtraExtraSmall(context)
|
||||
: STextStyles.smallMed12(context),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: isDesktop ? 10 : 8,
|
||||
),
|
||||
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("OrdinalsViewKeywordFieldKey"),
|
||||
controller: _keywordTextEditingController,
|
||||
focusNode: keywordTextFieldFocusNode,
|
||||
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(
|
||||
contentPadding: isDesktop
|
||||
? const EdgeInsets.symmetric(
|
||||
vertical: 10,
|
||||
horizontal: 16,
|
||||
)
|
||||
: null,
|
||||
suffixIcon: _keywordTextEditingController.text.isNotEmpty
|
||||
? Padding(
|
||||
padding: const EdgeInsets.only(right: 0),
|
||||
child: UnconstrainedBox(
|
||||
child: Row(
|
||||
children: [
|
||||
TextFieldIconButton(
|
||||
child: const XIcon(),
|
||||
onTap: () async {
|
||||
setState(() {
|
||||
_keywordTextEditingController.text = "";
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
: null,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (!isDesktop) const Spacer(),
|
||||
SizedBox(
|
||||
height: isDesktop ? 32 : 20,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: SecondaryButton(
|
||||
label: "Cancel",
|
||||
buttonHeight: isDesktop ? ButtonHeight.l : null,
|
||||
onPressed: () async {
|
||||
if (!isDesktop) {
|
||||
if (FocusScope.of(context).hasFocus) {
|
||||
FocusScope.of(context).unfocus();
|
||||
await Future<void>.delayed(
|
||||
const Duration(
|
||||
milliseconds: 75,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
if (mounted) {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 16,
|
||||
),
|
||||
Expanded(
|
||||
child: PrimaryButton(
|
||||
buttonHeight: isDesktop ? ButtonHeight.l : null,
|
||||
onPressed: () async {
|
||||
await _onApplyPressed();
|
||||
},
|
||||
label: "Save",
|
||||
),
|
||||
),
|
||||
if (isDesktop)
|
||||
const SizedBox(
|
||||
width: 32,
|
||||
),
|
||||
],
|
||||
),
|
||||
if (!isDesktop)
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _onApplyPressed() async {
|
||||
final filter = OrdinalFilter(
|
||||
isPunk: _isPunk,
|
||||
isMoonbird: _isMoonbird,
|
||||
from: _selectedFromDate,
|
||||
to: _selectedToDate,
|
||||
inscription: _inscriptionTextEditingController.text,
|
||||
keyword: _keywordTextEditingController.text,
|
||||
);
|
||||
|
||||
ref.read(ordinalFilterProvider.state).state = filter;
|
||||
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
}
|
|
@ -12,6 +12,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:stackwallet/models/ordinal.dart';
|
||||
import 'package:stackwallet/pages/ordinals/ordinals_filter_view.dart';
|
||||
import 'package:stackwallet/pages/ordinals/widgets/ordinals_list.dart';
|
||||
import 'package:stackwallet/themes/stack_colors.dart';
|
||||
import 'package:stackwallet/utilities/assets.dart';
|
||||
|
@ -104,7 +105,9 @@ class _OrdinalsViewState extends ConsumerState<OrdinalsView> {
|
|||
.topNavIconPrimary,
|
||||
),
|
||||
onPressed: () {
|
||||
// todo filter view
|
||||
Navigator.of(context).pushNamed(
|
||||
OrdinalsFilterView.routeName,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
|
|
|
@ -59,6 +59,7 @@ import 'package:stackwallet/pages/intro_view.dart';
|
|||
import 'package:stackwallet/pages/manage_favorites_view/manage_favorites_view.dart';
|
||||
import 'package:stackwallet/pages/notification_views/notifications_view.dart';
|
||||
import 'package:stackwallet/pages/ordinals/ordinal_details_view.dart';
|
||||
import 'package:stackwallet/pages/ordinals/ordinals_filter_view.dart';
|
||||
import 'package:stackwallet/pages/ordinals/ordinals_view.dart';
|
||||
import 'package:stackwallet/pages/paynym/add_new_paynym_follow_view.dart';
|
||||
import 'package:stackwallet/pages/paynym/paynym_claim_view.dart';
|
||||
|
@ -422,9 +423,6 @@ class RouteGenerator {
|
|||
return _routeError("${settings.name} invalid args: ${args.toString()}");
|
||||
|
||||
case OrdinalDetailsView.routeName:
|
||||
|
||||
print(args.runtimeType);
|
||||
|
||||
if (args is ({Ordinal ordinal, String walletId})) {
|
||||
return getRoute(
|
||||
shouldUseMaterialRoute: useMaterialPageRoute,
|
||||
|
@ -439,6 +437,12 @@ class RouteGenerator {
|
|||
}
|
||||
return _routeError("${settings.name} invalid args: ${args.toString()}");
|
||||
|
||||
case OrdinalsFilterView.routeName:
|
||||
return getRoute(
|
||||
shouldUseMaterialRoute: useMaterialPageRoute,
|
||||
builder: (_) => const OrdinalsFilterView(),
|
||||
settings: RouteSettings(name: settings.name));
|
||||
|
||||
case UtxoDetailsView.routeName:
|
||||
if (args is Tuple2<Id, String>) {
|
||||
return getRoute(
|
||||
|
|
Loading…
Reference in a new issue