desktop edit contact

This commit is contained in:
julian 2022-11-18 09:54:26 -06:00
parent 07f229f2a0
commit d4b7ec0f17
2 changed files with 462 additions and 366 deletions

View file

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:emojis/emoji.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
@ -7,14 +9,17 @@ import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart';
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/conditional_parent.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/primary_button.dart';
import 'package:stackwallet/widgets/desktop/secondary_button.dart';
import 'package:stackwallet/widgets/emoji_select_sheet.dart';
import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
import 'package:stackwallet/widgets/stack_text_field.dart';
import 'package:stackwallet/widgets/textfield_icon_button.dart';
import 'package:stackwallet/utilities/util.dart';
class EditContactNameEmojiView extends ConsumerStatefulWidget {
const EditContactNameEmojiView({
Key? key,
@ -69,7 +74,12 @@ class _EditContactNameEmojiViewState
final contact = ref.watch(addressBookServiceProvider
.select((value) => value.getContactById(contactId)));
return Scaffold(
final isDesktop = Util.isDesktop;
final double emojiSize = isDesktop ? 56 : 48;
return ConditionalParent(
condition: !isDesktop,
builder: (child) => Scaffold(
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
appBar: AppBar(
leading: AppBarBackButton(
@ -104,7 +114,19 @@ class _EditContactNameEmojiViewState
child: IntrinsicHeight(
child: Padding(
padding: const EdgeInsets.all(4),
child: child,
),
),
),
),
);
},
),
),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
GestureDetector(
onTap: () {
@ -114,6 +136,32 @@ class _EditContactNameEmojiViewState
});
return;
}
if (isDesktop) {
showDialog<dynamic>(
barrierColor: Colors.transparent,
context: context,
builder: (context) {
return const DesktopDialog(
maxHeight: 700,
maxWidth: 600,
child: Padding(
padding: EdgeInsets.only(
left: 32,
right: 20,
top: 32,
bottom: 32,
),
child: EmojiSelectSheet(),
),
);
}).then((value) {
if (value is Emoji) {
setState(() {
_selectedEmoji = value;
});
}
});
} else {
showModalBottomSheet<dynamic>(
backgroundColor: Colors.transparent,
context: context,
@ -130,17 +178,18 @@ class _EditContactNameEmojiViewState
});
}
});
}
},
child: SizedBox(
height: 48,
width: 48,
height: emojiSize,
width: emojiSize,
child: Stack(
children: [
Container(
height: 48,
width: 48,
height: emojiSize,
width: emojiSize,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24),
borderRadius: BorderRadius.circular(emojiSize / 2),
color: Theme.of(context)
.extension<StackColors>()!
.textFieldActiveBG,
@ -149,13 +198,14 @@ class _EditContactNameEmojiViewState
child: _selectedEmoji == null
? SvgPicture.asset(
Assets.svg.user,
height: 24,
width: 24,
height: emojiSize / 2,
width: emojiSize / 2,
)
: Text(
_selectedEmoji!.char,
style: STextStyles.pageTitleH1(
context),
style: isDesktop
? STextStyles.desktopH3(context)
: STextStyles.pageTitleH1(context),
),
),
),
@ -194,9 +244,58 @@ class _EditContactNameEmojiViewState
),
),
),
if (isDesktop)
const SizedBox(
width: 8,
),
if (isDesktop)
Expanded(
child: ClipRRect(
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
child: TextField(
autocorrect: Util.isDesktop ? false : true,
enableSuggestions: Util.isDesktop ? false : true,
controller: nameController,
focusNode: nameFocusNode,
style: STextStyles.field(context),
onChanged: (_) => setState(() {}),
decoration: standardInputDecoration(
"Enter contact name",
nameFocusNode,
context,
).copyWith(
suffixIcon: nameController.text.isNotEmpty
? Padding(
padding: const EdgeInsets.only(right: 0),
child: UnconstrainedBox(
child: Row(
children: [
TextFieldIconButton(
child: const XIcon(),
onTap: () async {
setState(() {
nameController.text = "";
});
},
),
],
),
),
)
: null,
),
),
),
),
],
),
if (!isDesktop)
const SizedBox(
height: 8,
),
if (!isDesktop)
ClipRRect(
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
@ -242,19 +341,11 @@ class _EditContactNameEmojiViewState
Row(
children: [
Expanded(
child: TextButton(
style: Theme.of(context)
.extension<StackColors>()!
.getSecondaryEnabledButtonColor(context),
child: Text(
"Cancel",
style: STextStyles.button(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark),
),
child: SecondaryButton(
label: "Cancel",
buttonHeight: isDesktop ? ButtonHeight.l : null,
onPressed: () async {
if (FocusScope.of(context).hasFocus) {
if (!isDesktop && FocusScope.of(context).hasFocus) {
FocusScope.of(context).unfocus();
await Future<void>.delayed(
const Duration(milliseconds: 75));
@ -269,55 +360,31 @@ class _EditContactNameEmojiViewState
width: 16,
),
Expanded(
child: Builder(
builder: (context) {
bool shouldEnableSave =
nameController.text.isNotEmpty;
return TextButton(
style: shouldEnableSave
? Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(
context)
: Theme.of(context)
.extension<StackColors>()!
.getPrimaryDisabledButtonColor(
context),
onPressed: shouldEnableSave
? () async {
if (FocusScope.of(context)
.hasFocus) {
child: PrimaryButton(
label: "Save",
enabled: nameController.text.isNotEmpty,
buttonHeight: isDesktop ? ButtonHeight.l : null,
onPressed: () async {
if (!isDesktop && FocusScope.of(context).hasFocus) {
FocusScope.of(context).unfocus();
await Future<void>.delayed(
const Duration(
milliseconds: 75),
const Duration(milliseconds: 75),
);
}
final editedContact =
contact.copyWith(
final editedContact = contact.copyWith(
shouldCopyEmojiWithNull: true,
name: nameController.text,
emojiChar: _selectedEmoji == null
? null
: _selectedEmoji!.char,
emojiChar:
_selectedEmoji == null ? null : _selectedEmoji!.char,
);
ref
.read(
addressBookServiceProvider)
.editContact(
unawaited(
ref.read(addressBookServiceProvider).editContact(
editedContact,
),
);
if (mounted) {
Navigator.of(context).pop();
}
}
: null,
child: Text(
"Save",
style: STextStyles.button(context),
),
);
},
),
),
@ -325,13 +392,6 @@ class _EditContactNameEmojiViewState
)
],
),
),
),
),
),
);
},
),
);
}
}

View file

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:stackwallet/notifications/show_flush_bar.dart';
import 'package:stackwallet/pages/address_book_views/subviews/edit_contact_name_emoji_view.dart';
import 'package:stackwallet/providers/global/address_book_service_provider.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/text_styles.dart';
@ -28,6 +29,147 @@ class _DesktopContactOptionsMenuPopupState
bool hoveredOnPencil = false;
bool hoveredOnTrash = false;
void editContact() {
// pop context menu
Navigator.of(context).pop();
showDialog<dynamic>(
context: context,
useSafeArea: true,
barrierDismissible: true,
builder: (_) => DesktopDialog(
maxWidth: 580,
maxHeight: 400,
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.only(
left: 32,
),
child: Text(
"Edit contact",
style: STextStyles.desktopH3(context),
),
),
const DesktopDialogCloseButton(),
],
),
Expanded(
child: Padding(
padding: const EdgeInsets.only(
top: 16,
left: 32,
right: 32,
bottom: 32,
),
child: EditContactNameEmojiView(
contactId: widget.contactId,
),
),
),
],
),
),
);
}
void attemptDeleteContact() {
final contact =
ref.read(addressBookServiceProvider).getContactById(widget.contactId);
// pop context menu
Navigator.of(context).pop();
showDialog<dynamic>(
context: context,
useSafeArea: true,
barrierDismissible: true,
builder: (_) => DesktopDialog(
maxWidth: 500,
maxHeight: 400,
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.only(
left: 32,
),
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,
);
},
),
),
),
],
)
],
),
),
),
],
),
),
);
}
@override
Widget build(BuildContext context) {
return Stack(
@ -148,9 +290,7 @@ class _DesktopContactOptionsMenuPopupState
1000,
),
),
onPressed: () {
print("should go to edit");
},
onPressed: editContact,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 25,
@ -213,111 +353,7 @@ class _DesktopContactOptionsMenuPopupState
1000,
),
),
onPressed: () {
final contact = ref
.read(addressBookServiceProvider)
.getContactById(widget.contactId);
// pop context menu
Navigator.of(context).pop();
showDialog<dynamic>(
context: context,
useSafeArea: true,
barrierDismissible: true,
builder: (_) => DesktopDialog(
maxWidth: 500,
maxHeight: 300,
child: Column(
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.only(
left: 32,
),
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,
);
},
),
),
),
],
)
],
),
),
),
],
),
),
);
},
onPressed: attemptDeleteContact,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 25,