mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-11-17 17:57:40 +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_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:stackwallet/models/ordinal.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/pages/ordinals/widgets/ordinals_list.dart';
|
||||||
import 'package:stackwallet/themes/stack_colors.dart';
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
import 'package:stackwallet/utilities/assets.dart';
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
|
@ -104,7 +105,9 @@ class _OrdinalsViewState extends ConsumerState<OrdinalsView> {
|
||||||
.topNavIconPrimary,
|
.topNavIconPrimary,
|
||||||
),
|
),
|
||||||
onPressed: () {
|
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/manage_favorites_view/manage_favorites_view.dart';
|
||||||
import 'package:stackwallet/pages/notification_views/notifications_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/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/ordinals/ordinals_view.dart';
|
||||||
import 'package:stackwallet/pages/paynym/add_new_paynym_follow_view.dart';
|
import 'package:stackwallet/pages/paynym/add_new_paynym_follow_view.dart';
|
||||||
import 'package:stackwallet/pages/paynym/paynym_claim_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()}");
|
return _routeError("${settings.name} invalid args: ${args.toString()}");
|
||||||
|
|
||||||
case OrdinalDetailsView.routeName:
|
case OrdinalDetailsView.routeName:
|
||||||
|
|
||||||
print(args.runtimeType);
|
|
||||||
|
|
||||||
if (args is ({Ordinal ordinal, String walletId})) {
|
if (args is ({Ordinal ordinal, String walletId})) {
|
||||||
return getRoute(
|
return getRoute(
|
||||||
shouldUseMaterialRoute: useMaterialPageRoute,
|
shouldUseMaterialRoute: useMaterialPageRoute,
|
||||||
|
@ -439,6 +437,12 @@ class RouteGenerator {
|
||||||
}
|
}
|
||||||
return _routeError("${settings.name} invalid args: ${args.toString()}");
|
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:
|
case UtxoDetailsView.routeName:
|
||||||
if (args is Tuple2<Id, String>) {
|
if (args is Tuple2<Id, String>) {
|
||||||
return getRoute(
|
return getRoute(
|
||||||
|
|
Loading…
Reference in a new issue