diff --git a/assets/translations/en.json b/assets/translations/en.json index 469230db4e08814564ee5deed0df8243984979fe..b5a7356136c9fff23919b30fd21c60a65dbbc8c7 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -111,9 +111,11 @@ "share_your_key": "Share your public key", "share_this_key": "Share", "form_save": "SAVE", + "form_contact_title_add": "Add a contact", "form_contact_title": "Edit contact", "form_contact_name": "Name", "form_contact_name_validation": "Please enter a name", + "form_contact_name_validation_pub_key": "Please enter a valid public key", "form_contact_notes": "Notes", "long_press_to_edit": "Slide to select this contact. Tap and hold to edit", "form_contact_pub_key": "Public key", diff --git a/assets/translations/es.json b/assets/translations/es.json index aa83be3705b4ab22ebf50d39e8964786374dc99b..1e2e1f3fc38ad30c9bfce7f2e1873f189af2527b 100644 --- a/assets/translations/es.json +++ b/assets/translations/es.json @@ -112,8 +112,10 @@ "share_this_key": "Comparte", "form_save": "GUARDAR", "form_contact_title": "Editar contacto", + "form_contact_title_add": "Añade un contacto", "form_contact_name": "Nombre", "form_contact_name_validation": "Por favor, ingresa un nombre", + "form_contact_name_validation_pub_key": "Por favor, ingresa una clave pública valida", "form_contact_notes": "Notas", "long_press_to_edit": "Desliza para seleccionar este contacto. Mantén pulsado para editar", "form_contact_pub_key": "Clave pública", diff --git a/lib/ui/screens/third_screen.dart b/lib/ui/screens/third_screen.dart index bb287ffe3c3d767bb5b51a65ca7b775b596192d9..eba4e21a2ded496b9ce79944aabc606607f0cef9 100644 --- a/lib/ui/screens/third_screen.dart +++ b/lib/ui/screens/third_screen.dart @@ -11,6 +11,7 @@ import '../qr_manager.dart'; import '../tutorial.dart'; import '../tutorial_keys.dart'; import '../widgets/card_drawer.dart'; +import '../widgets/third_screen/contact_form_dialog.dart'; import '../widgets/third_screen/contacts_page.dart'; import '../widgets/third_screen/third_tutorial.dart'; @@ -36,47 +37,75 @@ class _ThirdScreenState extends State<ThirdScreen> { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar(title: Text(tr('bottom_nav_trd')), actions: <Widget>[ - IconButton( - key: contactsQrKey, - icon: const Icon(Icons.qr_code), - onPressed: () async { - final String? pubKey = await QrManager.qrScan(context); - if (pubKey != null && validateKey(pubKey)) { - final Contact contact = - await ContactsCache().getContact(pubKey); - if (!mounted) { - return; - } - if (!context.read<ContactsCubit>().isContact(pubKey)) { - context.read<ContactsCubit>().addContact(contact); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text(tr('contact_added')), - ), - ); + appBar: AppBar(title: Text(tr('bottom_nav_trd')), actions: <Widget>[ + IconButton( + key: contactsQrKey, + icon: const Icon(Icons.qr_code), + onPressed: () async { + final String? pubKey = await QrManager.qrScan(context); + if (pubKey != null && validateKey(pubKey)) { + final Contact contact = + await ContactsCache().getContact(pubKey); + if (!mounted) { + return; + } + if (!context.read<ContactsCubit>().isContact(pubKey)) { + context.read<ContactsCubit>().addContact(contact); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(tr('contact_added')), + ), + ); + } else { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(tr('contact_already_exists')), + ), + ); + } } else { + if (!mounted) { + return; + } ScaffoldMessenger.of(context).showSnackBar( SnackBar( - content: Text(tr('contact_already_exists')), + content: Text(tr('wrong_public_key')), ), ); } - } else { - if (!mounted) { - return; - } - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text(tr('wrong_public_key')), - ), - ); - } - }), - const SizedBox(width: 5), - ]), - drawer: const CardDrawer(), - body: const ContactsPage(), - ); + }), + const SizedBox(width: 5), + ]), + drawer: const CardDrawer(), + body: const ContactsPage(), + floatingActionButton: FloatingActionButton( + onPressed: () async { + showDialog( + context: context, + builder: (BuildContext context) { + return ContactFormDialog( + contact: const Contact( + name: '', + pubKey: '', + ), + isNew: true, + onSave: (Contact c) { + context.read<ContactsCubit>().addContact(c); + ContactsCache().saveContact(c); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(tr('contact_added')), + ), + ); + }); + }); + }, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all( + Radius.circular(50.0), + ), + ), + child: const Icon(Icons.add), + )); } } diff --git a/lib/ui/widgets/first_screen/contact_fav_icon.dart b/lib/ui/widgets/first_screen/contact_fav_icon.dart index ae89622ea35e28c18e7a4572e001749889efd44b..05d9e58476e907dc24159df38d8ace027c0e9e49 100644 --- a/lib/ui/widgets/first_screen/contact_fav_icon.dart +++ b/lib/ui/widgets/first_screen/contact_fav_icon.dart @@ -5,7 +5,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import '../../../data/models/contact.dart'; import '../../../data/models/contact_cubit.dart'; import '../../contacts_cache.dart'; -import '../third_screen/contact_edit_dialog.dart'; +import '../third_screen/contact_form_dialog.dart'; class ContactFavIcon extends StatelessWidget { const ContactFavIcon({ @@ -37,7 +37,7 @@ class ContactFavIcon extends StatelessWidget { showDialog( context: context, builder: (BuildContext context) { - return ContactEditDialog( + return ContactFormDialog( contact: contact, onSave: (Contact c) { context.read<ContactsCubit>().updateContact(c); diff --git a/lib/ui/widgets/fourth_screen/transaction_item.dart b/lib/ui/widgets/fourth_screen/transaction_item.dart index 1d14392c0a9ffcd100c3f812e524fcc58ea14e6b..ba6618738d1d94644bf8bc559a62a4f5d7d3243c 100644 --- a/lib/ui/widgets/fourth_screen/transaction_item.dart +++ b/lib/ui/widgets/fourth_screen/transaction_item.dart @@ -16,7 +16,7 @@ import '../../../shared_prefs.dart'; import '../../contacts_cache.dart'; import '../../pay_helper.dart'; import '../../ui_helpers.dart'; -import '../third_screen/contact_edit_dialog.dart'; +import '../third_screen/contact_form_dialog.dart'; class TransactionListItem extends StatelessWidget { const TransactionListItem( @@ -176,7 +176,7 @@ class TransactionListItem extends StatelessWidget { showDialog( context: context, builder: (BuildContext context) { - return ContactEditDialog( + return ContactFormDialog( contact: newContact, onSave: (Contact c) { context.read<ContactsCubit>().updateContact(c); diff --git a/lib/ui/widgets/third_screen/contact_edit_dialog.dart b/lib/ui/widgets/third_screen/contact_form_dialog.dart similarity index 53% rename from lib/ui/widgets/third_screen/contact_edit_dialog.dart rename to lib/ui/widgets/third_screen/contact_form_dialog.dart index 4d14dc6334e3aff9b31566c8a1d00d9fa214d190..67659d742b253179f7b26f993319a74bac1ec927 100644 --- a/lib/ui/widgets/third_screen/contact_edit_dialog.dart +++ b/lib/ui/widgets/third_screen/contact_form_dialog.dart @@ -5,18 +5,23 @@ import '../../../data/models/contact.dart'; import '../../../g1/g1_helper.dart'; import '../../ui_helpers.dart'; -class ContactEditDialog extends StatefulWidget { - const ContactEditDialog( - {super.key, required this.contact, required this.onSave}); +class ContactFormDialog extends StatefulWidget { + const ContactFormDialog({ + super.key, + required this.contact, + required this.onSave, + this.isNew = false, + }); final Contact contact; final Function(Contact) onSave; + final bool isNew; @override - State<ContactEditDialog> createState() => _ContactEditDialogState(); + State<ContactFormDialog> createState() => _ContactFormDialogState(); } -class _ContactEditDialogState extends State<ContactEditDialog> { +class _ContactFormDialogState extends State<ContactFormDialog> { final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); late Contact _updatedContact; @@ -29,36 +34,53 @@ class _ContactEditDialogState extends State<ContactEditDialog> { @override Widget build(BuildContext context) { return AlertDialog( - title: Text(tr('form_contact_title')), + title: Text( + tr(widget.isNew ? 'form_contact_title_add' : 'form_contact_title')), content: Form( key: _formKey, child: Column( mainAxisSize: MainAxisSize.min, children: <Widget>[ - Row(mainAxisSize: MainAxisSize.min, children: <Widget>[ - Flexible( - child: TextFormField( - // maxLines: 2, - initialValue: humanizePubKey(_updatedContact.pubKey), + if (!widget.isNew) + Row(mainAxisSize: MainAxisSize.min, children: <Widget>[ + Flexible( + child: TextFormField( + // maxLines: 2, + initialValue: humanizePubKey(_updatedContact.pubKey), + decoration: InputDecoration( + labelText: tr('form_contact_pub_key'), + ), + enabled: false, + )), + GestureDetector( + onTap: () { + showQrDialog( + context: context, + publicKey: getFullPubKey(_updatedContact.pubKey), + noTitle: true, + feedbackText: 'some_key_copied_to_clipboard'); + }, + child: const Icon(Icons.qr_code, size: 50), + ), + ]), + if (widget.isNew) + TextFormField( + validator: (String? value) { + if (value == null || value.isEmpty || !validateKey(value)) { + return tr('form_contact_name_validation_pub_key'); + } + return null; + }, decoration: InputDecoration( labelText: tr('form_contact_pub_key'), ), - enabled: false, - )), - GestureDetector( - onTap: () { - showQrDialog( - context: context, - publicKey: getFullPubKey(_updatedContact.pubKey), - noTitle: true, - feedbackText: 'some_key_copied_to_clipboard'); + onChanged: (String? value) { + _updatedContact = _updatedContact.copyWith(pubKey: value); }, - child: const Icon(Icons.qr_code, size: 50), ), - ]), TextFormField( initialValue: _updatedContact.name, - decoration: const InputDecoration(labelText: 'Name'), + decoration: InputDecoration(labelText: tr('form_contact_name')), validator: (String? value) { if (value == null || value.isEmpty) { return tr('form_contact_name_validation'); diff --git a/lib/ui/widgets/third_screen/contacts_page.dart b/lib/ui/widgets/third_screen/contacts_page.dart index d2002e5b446043e904b2a4a4e90fa97707f722fa..994356e183c011621aea05b652ea1765faebca6b 100644 --- a/lib/ui/widgets/third_screen/contacts_page.dart +++ b/lib/ui/widgets/third_screen/contacts_page.dart @@ -12,7 +12,7 @@ import '../../../g1/g1_helper.dart'; import '../../contacts_cache.dart'; import '../../ui_helpers.dart'; import '../bottom_widget.dart'; -import 'contact_edit_dialog.dart'; +import 'contact_form_dialog.dart'; class ContactsPage extends StatefulWidget { const ContactsPage({super.key}); @@ -134,7 +134,7 @@ class _ContactsPageState extends State<ContactsPage> { showDialog( context: context, builder: (BuildContext context) { - return ContactEditDialog( + return ContactFormDialog( contact: contact, onSave: (Contact c) { context