desktop tx details + edit note ui

This commit is contained in:
julian 2022-10-29 13:35:03 -06:00
parent 1f6338892e
commit 5fd47de9a2
7 changed files with 1302 additions and 609 deletions

View file

@ -23,6 +23,7 @@ import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart'; import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart'; import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart'; import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
import 'package:stackwallet/widgets/desktop/secondary_button.dart'; import 'package:stackwallet/widgets/desktop/secondary_button.dart';
import 'package:stackwallet/widgets/icon_widgets/x_icon.dart'; import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
@ -865,16 +866,31 @@ class _DesktopTransactionCardRowState
); );
return; return;
} }
unawaited( if (Util.isDesktop) {
Navigator.of(context).pushNamed( await showDialog<void>(
TransactionDetailsView.routeName, context: context,
arguments: Tuple3( builder: (context) => DesktopDialog(
_transaction, maxHeight: MediaQuery.of(context).size.height - 64,
coin, maxWidth: 580,
walletId, child: TransactionDetailsView(
transaction: _transaction,
coin: coin,
walletId: walletId,
),
), ),
), );
); } else {
unawaited(
Navigator.of(context).pushNamed(
TransactionDetailsView.routeName,
arguments: Tuple3(
_transaction,
coin,
walletId,
),
),
);
}
}, },
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(

View file

@ -4,13 +4,14 @@ import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.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/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
import 'package:stackwallet/widgets/desktop/primary_button.dart';
import 'package:stackwallet/widgets/icon_widgets/x_icon.dart'; import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
import 'package:stackwallet/widgets/stack_text_field.dart'; import 'package:stackwallet/widgets/stack_text_field.dart';
import 'package:stackwallet/widgets/textfield_icon_button.dart'; import 'package:stackwallet/widgets/textfield_icon_button.dart';
import 'package:stackwallet/utilities/util.dart';
class EditNoteView extends ConsumerStatefulWidget { class EditNoteView extends ConsumerStatefulWidget {
const EditNoteView({ const EditNoteView({
Key? key, Key? key,
@ -33,8 +34,11 @@ class _EditNoteViewState extends ConsumerState<EditNoteView> {
late final TextEditingController _noteController; late final TextEditingController _noteController;
final noteFieldFocusNode = FocusNode(); final noteFieldFocusNode = FocusNode();
late final bool isDesktop;
@override @override
void initState() { void initState() {
isDesktop = Util.isDesktop;
_noteController = TextEditingController(); _noteController = TextEditingController();
_noteController.text = widget.note; _noteController.text = widget.note;
super.initState(); super.initState();
@ -50,29 +54,178 @@ class _EditNoteViewState extends ConsumerState<EditNoteView> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
backgroundColor: Theme.of(context).extension<StackColors>()!.background, backgroundColor: isDesktop
appBar: AppBar( ? Colors.transparent
backgroundColor: : Theme.of(context).extension<StackColors>()!.background,
Theme.of(context).extension<StackColors>()!.background, appBar: isDesktop
leading: AppBarBackButton( ? null
onPressed: () async { : AppBar(
if (FocusScope.of(context).hasFocus) { backgroundColor:
FocusScope.of(context).unfocus(); Theme.of(context).extension<StackColors>()!.background,
await Future<void>.delayed(const Duration(milliseconds: 75)); leading: AppBarBackButton(
} onPressed: () async {
if (mounted) { if (FocusScope.of(context).hasFocus) {
Navigator.of(context).pop(); FocusScope.of(context).unfocus();
} await Future<void>.delayed(
}, const Duration(milliseconds: 75));
), }
title: Text( if (mounted) {
"Edit note", Navigator.of(context).pop();
style: STextStyles.navBarTitle(context), }
), },
),
title: Text(
"Edit note",
style: STextStyles.navBarTitle(context),
),
),
body: MobileEditNoteScaffold(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
if (isDesktop)
Padding(
padding: const EdgeInsets.only(
left: 32,
bottom: 12,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Edit note",
style: STextStyles.desktopH3(context),
),
const DesktopDialogCloseButton(),
],
),
),
Padding(
padding: isDesktop
? const EdgeInsets.symmetric(
horizontal: 32,
)
: const EdgeInsets.all(0),
child: ClipRRect(
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
child: TextField(
autocorrect: Util.isDesktop ? false : true,
enableSuggestions: Util.isDesktop ? false : true,
controller: _noteController,
style: isDesktop
? STextStyles.desktopTextExtraSmall(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textFieldActiveText,
height: 1.8,
)
: STextStyles.field(context),
focusNode: noteFieldFocusNode,
decoration: standardInputDecoration(
"Note",
noteFieldFocusNode,
context,
desktopMed: isDesktop,
).copyWith(
contentPadding: isDesktop
? const EdgeInsets.only(
left: 16,
top: 11,
bottom: 12,
right: 5,
)
: null,
suffixIcon: _noteController.text.isNotEmpty
? Padding(
padding: const EdgeInsets.only(right: 0),
child: UnconstrainedBox(
child: Row(
children: [
TextFieldIconButton(
child: const XIcon(),
onTap: () async {
setState(() {
_noteController.text = "";
});
},
),
],
),
),
)
: null,
),
),
),
),
// if (!isDesktop)
const Spacer(),
if (isDesktop)
Padding(
padding: const EdgeInsets.all(32),
child: PrimaryButton(
label: "Save",
onPressed: () async {
await ref
.read(
notesServiceChangeNotifierProvider(widget.walletId))
.editOrAddNote(
txid: widget.txid,
note: _noteController.text,
);
if (mounted) {
Navigator.of(context).pop();
}
},
),
),
if (!isDesktop)
TextButton(
onPressed: () async {
await ref
.read(notesServiceChangeNotifierProvider(widget.walletId))
.editOrAddNote(
txid: widget.txid,
note: _noteController.text,
);
if (mounted) {
Navigator.of(context).pop();
}
},
style: Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context),
child: Text(
"Save",
style: STextStyles.button(context),
),
)
],
), ),
body: Padding( ),
padding: const EdgeInsets.all(12), );
child: LayoutBuilder(builder: (context, constraints) { }
}
class MobileEditNoteScaffold extends StatelessWidget {
const MobileEditNoteScaffold({
Key? key,
required this.child,
}) : super(key: key);
final Widget child;
@override
Widget build(BuildContext context) {
if (Util.isDesktop) {
return child;
} else {
return Padding(
padding: const EdgeInsets.all(12),
child: LayoutBuilder(
builder: (context, constraints) {
return SingleChildScrollView( return SingleChildScrollView(
child: ConstrainedBox( child: ConstrainedBox(
constraints: BoxConstraints( constraints: BoxConstraints(
@ -81,75 +234,14 @@ class _EditNoteViewState extends ConsumerState<EditNoteView> {
child: IntrinsicHeight( child: IntrinsicHeight(
child: Padding( child: Padding(
padding: const EdgeInsets.all(4), padding: const EdgeInsets.all(4),
child: Column( child: child,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
child: TextField(
autocorrect: Util.isDesktop ? false : true,
enableSuggestions: Util.isDesktop ? false : true,
controller: _noteController,
style: STextStyles.field(context),
focusNode: noteFieldFocusNode,
decoration: standardInputDecoration(
"Note",
noteFieldFocusNode,
context,
).copyWith(
suffixIcon: _noteController.text.isNotEmpty
? Padding(
padding: const EdgeInsets.only(right: 0),
child: UnconstrainedBox(
child: Row(
children: [
TextFieldIconButton(
child: const XIcon(),
onTap: () async {
setState(() {
_noteController.text = "";
});
},
),
],
),
),
)
: null,
),
),
),
const Spacer(),
TextButton(
onPressed: () async {
await ref
.read(notesServiceChangeNotifierProvider(
widget.walletId))
.editOrAddNote(
txid: widget.txid,
note: _noteController.text,
);
if (mounted) {
Navigator.of(context).pop();
}
},
style: Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context),
child: Text(
"Save",
style: STextStyles.button(context),
),
)
],
),
), ),
), ),
), ),
); );
}), },
)); ),
);
}
} }
} }

View file

@ -0,0 +1,27 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
class CopyIcon extends StatelessWidget {
const CopyIcon({
Key? key,
this.width = 18,
this.height = 18,
this.color,
}) : super(key: key);
final double width;
final double height;
final Color? color;
@override
Widget build(BuildContext context) {
return SvgPicture.asset(
Assets.svg.copy,
width: width,
height: height,
color: color ?? Theme.of(context).extension<StackColors>()!.textDark3,
);
}
}

View file

@ -0,0 +1,27 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
class PencilIcon extends StatelessWidget {
const PencilIcon({
Key? key,
this.width = 18,
this.height = 18,
this.color,
}) : super(key: key);
final double width;
final double height;
final Color? color;
@override
Widget build(BuildContext context) {
return SvgPicture.asset(
Assets.svg.pencil,
width: width,
height: height,
color: color ?? Theme.of(context).extension<StackColors>()!.textDark3,
);
}
}

View file

@ -14,6 +14,7 @@ import 'package:stackwallet/utilities/format.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart'; import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
class TransactionCard extends ConsumerStatefulWidget { class TransactionCard extends ConsumerStatefulWidget {
@ -138,16 +139,31 @@ class _TransactionCardState extends ConsumerState<TransactionCard> {
)); ));
return; return;
} }
unawaited( if (Util.isDesktop) {
Navigator.of(context).pushNamed( await showDialog<void>(
TransactionDetailsView.routeName, context: context,
arguments: Tuple3( builder: (context) => DesktopDialog(
_transaction, maxHeight: MediaQuery.of(context).size.height - 64,
coin, maxWidth: 580,
walletId, child: TransactionDetailsView(
transaction: _transaction,
coin: coin,
walletId: walletId,
),
), ),
), );
); } else {
unawaited(
Navigator.of(context).pushNamed(
TransactionDetailsView.routeName,
arguments: Tuple3(
_transaction,
coin,
walletId,
),
),
);
}
}, },
child: Padding( child: Padding(
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(8),

View file

@ -42,7 +42,7 @@ packages:
name: archive name: archive
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.3.0" version: "3.1.11"
args: args:
dependency: transitive dependency: transitive
description: description:
@ -63,7 +63,7 @@ packages:
name: async name: async
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.9.0" version: "2.8.2"
barcode_scan2: barcode_scan2:
dependency: "direct main" dependency: "direct main"
description: description:
@ -190,7 +190,14 @@ packages:
name: characters name: characters
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.1" version: "1.2.0"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.1"
checked_yaml: checked_yaml:
dependency: transitive dependency: transitive
description: description:
@ -204,7 +211,7 @@ packages:
name: clock name: clock
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.1" version: "1.1.0"
code_builder: code_builder:
dependency: transitive dependency: transitive
description: description:
@ -274,7 +281,7 @@ packages:
name: coverage name: coverage
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.5.0" version: "1.2.0"
cross_file: cross_file:
dependency: transitive dependency: transitive
description: description:
@ -428,7 +435,7 @@ packages:
name: fake_async name: fake_async
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.1" version: "1.3.0"
ffi: ffi:
dependency: "direct main" dependency: "direct main"
description: description:
@ -857,21 +864,21 @@ packages:
name: matcher name: matcher
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.12.12" version: "0.12.11"
material_color_utilities: material_color_utilities:
dependency: transitive dependency: transitive
description: description:
name: material_color_utilities name: material_color_utilities
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.5" version: "0.1.4"
meta: meta:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.0" version: "1.7.0"
mime: mime:
dependency: transitive dependency: transitive
description: description:
@ -983,7 +990,7 @@ packages:
name: path name: path
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.2" version: "1.8.1"
path_drawing: path_drawing:
dependency: transitive dependency: transitive
description: description:
@ -1359,7 +1366,7 @@ packages:
name: source_span name: source_span
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.9.0" version: "1.8.2"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
@ -1417,35 +1424,35 @@ packages:
name: sync_http name: sync_http
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.3.1" version: "0.3.0"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:
name: term_glyph name: term_glyph
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.1" version: "1.2.0"
test: test:
dependency: transitive dependency: transitive
description: description:
name: test name: test
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.21.4" version: "1.21.1"
test_api: test_api:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.4.12" version: "0.4.9"
test_core: test_core:
dependency: transitive dependency: transitive
description: description:
name: test_core name: test_core
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.4.16" version: "0.4.13"
time: time:
dependency: transitive dependency: transitive
description: description:
@ -1494,7 +1501,7 @@ packages:
name: typed_data name: typed_data
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.1" version: "1.3.0"
universal_io: universal_io:
dependency: transitive dependency: transitive
description: description:
@ -1578,7 +1585,7 @@ packages:
name: vm_service name: vm_service
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "9.0.0" version: "8.2.2"
wakelock: wakelock:
dependency: "direct main" dependency: "direct main"
description: description: