add delete contact functionality for desktop

This commit is contained in:
julian 2022-11-18 09:07:31 -06:00
parent 17e4976a89
commit aa966a106d
2 changed files with 260 additions and 135 deletions

View file

@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:stackwallet/models/contact.dart'; import 'package:stackwallet/models/contact.dart';
import 'package:stackwallet/models/paymint/transactions_model.dart'; import 'package:stackwallet/models/paymint/transactions_model.dart';
import 'package:stackwallet/notifications/show_flush_bar.dart';
import 'package:stackwallet/pages/address_book_views/subviews/add_new_contact_address_view.dart'; import 'package:stackwallet/pages/address_book_views/subviews/add_new_contact_address_view.dart';
import 'package:stackwallet/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_card.dart'; import 'package:stackwallet/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_card.dart';
import 'package:stackwallet/providers/global/address_book_service_provider.dart'; import 'package:stackwallet/providers/global/address_book_service_provider.dart';
@ -15,6 +16,8 @@ import 'package:stackwallet/utilities/theme/stack_colors.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/custom_buttons/blue_text_button.dart'; import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog.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/desktop/secondary_button.dart';
import 'package:stackwallet/widgets/loading_indicator.dart'; import 'package:stackwallet/widgets/loading_indicator.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart';
@ -74,8 +77,16 @@ class _DesktopContactDetailsState extends ConsumerState<DesktopContactDetails> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final contact = ref.watch(addressBookServiceProvider // provider hack to prevent trying to update widget with deleted contact
.select((value) => value.getContactById(widget.contactId))); Contact? _contact;
try {
_contact = ref.watch(addressBookServiceProvider
.select((value) => value.getContactById(widget.contactId)));
} catch (_) {
return Container();
}
final contact = _contact!;
return Row( return Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -129,22 +140,23 @@ class _DesktopContactDetailsState extends ConsumerState<DesktopContactDetails> {
), ),
], ],
), ),
SecondaryButton( if (widget.contactId != "default")
label: "Options", SecondaryButton(
width: 96, label: "Options",
buttonHeight: ButtonHeight.xxs, width: 96,
onPressed: () async { buttonHeight: ButtonHeight.xxs,
await showDialog<void>( onPressed: () async {
context: context, await showDialog<void>(
barrierColor: Colors.transparent, context: context,
builder: (context) { barrierColor: Colors.transparent,
return DesktopContactOptionsMenuPopup( builder: (context) {
contactId: contact.id, return DesktopContactOptionsMenuPopup(
); contactId: contact.id,
}, );
); },
}, );
), },
),
], ],
), ),
const SizedBox( const SizedBox(
@ -453,132 +465,238 @@ class _DesktopContactOptionsMenuPopupState
), ),
), ),
), ),
const SizedBox( if (widget.contactId != "default")
height: 2, const SizedBox(
), height: 2,
MouseRegion( ),
onEnter: (_) { if (widget.contactId != "default")
setState(() { MouseRegion(
hoveredOnPencil = true; onEnter: (_) {
}); setState(() {
}, hoveredOnPencil = true;
onExit: (_) { });
setState(() {
hoveredOnPencil = false;
});
},
child: RawMaterialButton(
hoverColor: Theme.of(context)
.extension<StackColors>()!
.textFieldDefaultBG,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
1000,
),
),
onPressed: () {
print("should go to edit");
}, },
child: Padding( onExit: (_) {
padding: const EdgeInsets.symmetric( setState(() {
horizontal: 25, hoveredOnPencil = false;
vertical: 16, });
},
child: RawMaterialButton(
hoverColor: Theme.of(context)
.extension<StackColors>()!
.textFieldDefaultBG,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
1000,
),
), ),
child: Row( onPressed: () {
children: [ print("should go to edit");
SvgPicture.asset( },
Assets.svg.pencil, child: Padding(
width: 24, padding: const EdgeInsets.symmetric(
height: 22, horizontal: 25,
color: hoveredOnPencil vertical: 16,
? Theme.of(context) ),
.extension<StackColors>()! child: Row(
.textDark children: [
: Theme.of(context) SvgPicture.asset(
.extension<StackColors>()! Assets.svg.pencil,
.textFieldDefaultSearchIconLeft, width: 24,
), height: 22,
const SizedBox( color: hoveredOnPencil
width: 12, ? Theme.of(context)
), .extension<StackColors>()!
Text( .textDark
"Edit contact", : Theme.of(context)
style: STextStyles.desktopTextExtraExtraSmall( .extension<StackColors>()!
context) .textFieldDefaultSearchIconLeft,
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textDark,
), ),
) const SizedBox(
], width: 12,
),
Text(
"Edit contact",
style: STextStyles.desktopTextExtraExtraSmall(
context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textDark,
),
)
],
),
), ),
), ),
), ),
), if (widget.contactId != "default")
const SizedBox( const SizedBox(
height: 2, height: 2,
), ),
MouseRegion( if (widget.contactId != "default")
onEnter: (_) { MouseRegion(
setState(() { onEnter: (_) {
hoveredOnTrash = true; setState(() {
}); hoveredOnTrash = true;
}, });
onExit: (_) {
setState(() {
hoveredOnTrash = false;
});
},
child: RawMaterialButton(
hoverColor: Theme.of(context)
.extension<StackColors>()!
.textFieldDefaultBG,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
1000,
),
),
onPressed: () {
print("should delete contact");
}, },
child: Padding( onExit: (_) {
padding: const EdgeInsets.symmetric( setState(() {
horizontal: 25, hoveredOnTrash = false;
vertical: 16, });
},
child: RawMaterialButton(
hoverColor: Theme.of(context)
.extension<StackColors>()!
.textFieldDefaultBG,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
1000,
),
), ),
child: Row( onPressed: () {
children: [ final contact = ref
SvgPicture.asset( .read(addressBookServiceProvider)
Assets.svg.trash, .getContactById(widget.contactId);
width: 24,
height: 22, // pop context menu
color: hoveredOnTrash Navigator.of(context).pop();
? Theme.of(context)
.extension<StackColors>()! showDialog<dynamic>(
.textDark context: context,
: Theme.of(context) useSafeArea: true,
.extension<StackColors>()! barrierDismissible: true,
.textFieldDefaultSearchIconLeft, builder: (_) => DesktopDialog(
), maxWidth: 500,
const SizedBox( maxHeight: 300,
width: 12, child: Column(
), children: [
Text( Row(
"Delete contact", mainAxisAlignment:
style: STextStyles.desktopTextExtraExtraSmall( MainAxisAlignment.spaceBetween,
context) children: [
.copyWith( Padding(
color: Theme.of(context) padding: const EdgeInsets.only(
.extension<StackColors>()! left: 32,
.textDark, ),
child: Text(
"Delete ${contact.name}?",
style: STextStyles.desktopH3(context),
),
),
const DesktopDialogCloseButton(),
],
),
Expanded(
child: Padding(
padding: const EdgeInsets.only(
left: 32,
right: 32,
bottom: 32,
),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
const Spacer(
flex: 1,
),
Text(
"Contact will be deleted permanently!",
style: STextStyles.desktopTextSmall(
context),
),
const Spacer(
flex: 2,
),
Row(
children: [
Expanded(
child: SecondaryButton(
label: "Cancel",
onPressed:
Navigator.of(context).pop,
buttonHeight: ButtonHeight.l,
),
),
const SizedBox(
width: 16,
),
Expanded(
child: Consumer(
builder: (context, ref, __) =>
PrimaryButton(
label: "Delete",
buttonHeight:
ButtonHeight.l,
onPressed: () {
ref
.read(
addressBookServiceProvider)
.removeContact(
contact.id);
Navigator.of(context)
.pop();
showFloatingFlushBar(
type: FlushBarType
.success,
message:
"${contact.name} deleted",
context: context,
);
},
),
),
),
],
)
],
),
),
),
],
), ),
) ),
], );
},
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 25,
vertical: 16,
),
child: Row(
children: [
SvgPicture.asset(
Assets.svg.trash,
width: 24,
height: 22,
color: hoveredOnTrash
? Theme.of(context)
.extension<StackColors>()!
.textDark
: Theme.of(context)
.extension<StackColors>()!
.textFieldDefaultSearchIconLeft,
),
const SizedBox(
width: 12,
),
Text(
"Delete contact",
style: STextStyles.desktopTextExtraExtraSmall(
context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textDark,
),
)
],
),
), ),
), ),
), ),
),
], ],
), ),
), ),

View file

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; 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/contact.dart';
import 'package:stackwallet/pages/address_book_views/subviews/contact_popup.dart'; import 'package:stackwallet/pages/address_book_views/subviews/contact_popup.dart';
import 'package:stackwallet/providers/global/address_book_service_provider.dart'; import 'package:stackwallet/providers/global/address_book_service_provider.dart';
import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/assets.dart';
@ -44,10 +45,16 @@ class _AddressBookCardState extends ConsumerState<AddressBookCard> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// final isTiny = SizingUtilities.isTinyWidth(context); // provider hack to prevent trying to update widget with deleted contact
Contact? _contact;
try {
_contact = ref.watch(addressBookServiceProvider
.select((value) => value.getContactById(contactId)));
} catch (_) {
return Container();
}
final contact = ref.watch(addressBookServiceProvider final contact = _contact!;
.select((value) => value.getContactById(contactId)));
final List<Coin> coins = []; final List<Coin> coins = [];
for (var element in contact.addresses) { for (var element in contact.addresses) {