Skip to content
Snippets Groups Projects
Commit 87b45991 authored by vjrj's avatar vjrj
Browse files

Add contacts

parent 331bcb37
No related branches found
No related tags found
No related merge requests found
...@@ -111,9 +111,11 @@ ...@@ -111,9 +111,11 @@
"share_your_key": "Share your public key", "share_your_key": "Share your public key",
"share_this_key": "Share", "share_this_key": "Share",
"form_save": "SAVE", "form_save": "SAVE",
"form_contact_title_add": "Add a contact",
"form_contact_title": "Edit contact", "form_contact_title": "Edit contact",
"form_contact_name": "Name", "form_contact_name": "Name",
"form_contact_name_validation": "Please enter a 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", "form_contact_notes": "Notes",
"long_press_to_edit": "Slide to select this contact. Tap and hold to edit", "long_press_to_edit": "Slide to select this contact. Tap and hold to edit",
"form_contact_pub_key": "Public key", "form_contact_pub_key": "Public key",
......
...@@ -112,8 +112,10 @@ ...@@ -112,8 +112,10 @@
"share_this_key": "Comparte", "share_this_key": "Comparte",
"form_save": "GUARDAR", "form_save": "GUARDAR",
"form_contact_title": "Editar contacto", "form_contact_title": "Editar contacto",
"form_contact_title_add": "Añade un contacto",
"form_contact_name": "Nombre", "form_contact_name": "Nombre",
"form_contact_name_validation": "Por favor, ingresa un 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", "form_contact_notes": "Notas",
"long_press_to_edit": "Desliza para seleccionar este contacto. Mantén pulsado para editar", "long_press_to_edit": "Desliza para seleccionar este contacto. Mantén pulsado para editar",
"form_contact_pub_key": "Clave pública", "form_contact_pub_key": "Clave pública",
......
...@@ -11,6 +11,7 @@ import '../qr_manager.dart'; ...@@ -11,6 +11,7 @@ import '../qr_manager.dart';
import '../tutorial.dart'; import '../tutorial.dart';
import '../tutorial_keys.dart'; import '../tutorial_keys.dart';
import '../widgets/card_drawer.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/contacts_page.dart';
import '../widgets/third_screen/third_tutorial.dart'; import '../widgets/third_screen/third_tutorial.dart';
...@@ -36,47 +37,75 @@ class _ThirdScreenState extends State<ThirdScreen> { ...@@ -36,47 +37,75 @@ class _ThirdScreenState extends State<ThirdScreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar(title: Text(tr('bottom_nav_trd')), actions: <Widget>[ appBar: AppBar(title: Text(tr('bottom_nav_trd')), actions: <Widget>[
IconButton( IconButton(
key: contactsQrKey, key: contactsQrKey,
icon: const Icon(Icons.qr_code), icon: const Icon(Icons.qr_code),
onPressed: () async { onPressed: () async {
final String? pubKey = await QrManager.qrScan(context); final String? pubKey = await QrManager.qrScan(context);
if (pubKey != null && validateKey(pubKey)) { if (pubKey != null && validateKey(pubKey)) {
final Contact contact = final Contact contact =
await ContactsCache().getContact(pubKey); await ContactsCache().getContact(pubKey);
if (!mounted) { if (!mounted) {
return; return;
} }
if (!context.read<ContactsCubit>().isContact(pubKey)) { if (!context.read<ContactsCubit>().isContact(pubKey)) {
context.read<ContactsCubit>().addContact(contact); context.read<ContactsCubit>().addContact(contact);
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text(tr('contact_added')), content: Text(tr('contact_added')),
), ),
); );
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(tr('contact_already_exists')),
),
);
}
} else { } else {
if (!mounted) {
return;
}
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text(tr('contact_already_exists')), content: Text(tr('wrong_public_key')),
), ),
); );
} }
} else { }),
if (!mounted) { const SizedBox(width: 5),
return; ]),
} drawer: const CardDrawer(),
ScaffoldMessenger.of(context).showSnackBar( body: const ContactsPage(),
SnackBar( floatingActionButton: FloatingActionButton(
content: Text(tr('wrong_public_key')), onPressed: () async {
), showDialog(
); context: context,
} builder: (BuildContext context) {
}), return ContactFormDialog(
const SizedBox(width: 5), contact: const Contact(
]), name: '',
drawer: const CardDrawer(), pubKey: '',
body: const ContactsPage(), ),
); 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),
));
} }
} }
...@@ -5,7 +5,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; ...@@ -5,7 +5,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../data/models/contact.dart'; import '../../../data/models/contact.dart';
import '../../../data/models/contact_cubit.dart'; import '../../../data/models/contact_cubit.dart';
import '../../contacts_cache.dart'; import '../../contacts_cache.dart';
import '../third_screen/contact_edit_dialog.dart'; import '../third_screen/contact_form_dialog.dart';
class ContactFavIcon extends StatelessWidget { class ContactFavIcon extends StatelessWidget {
const ContactFavIcon({ const ContactFavIcon({
...@@ -37,7 +37,7 @@ class ContactFavIcon extends StatelessWidget { ...@@ -37,7 +37,7 @@ class ContactFavIcon extends StatelessWidget {
showDialog( showDialog(
context: context, context: context,
builder: (BuildContext context) { builder: (BuildContext context) {
return ContactEditDialog( return ContactFormDialog(
contact: contact, contact: contact,
onSave: (Contact c) { onSave: (Contact c) {
context.read<ContactsCubit>().updateContact(c); context.read<ContactsCubit>().updateContact(c);
......
...@@ -16,7 +16,7 @@ import '../../../shared_prefs.dart'; ...@@ -16,7 +16,7 @@ import '../../../shared_prefs.dart';
import '../../contacts_cache.dart'; import '../../contacts_cache.dart';
import '../../pay_helper.dart'; import '../../pay_helper.dart';
import '../../ui_helpers.dart'; import '../../ui_helpers.dart';
import '../third_screen/contact_edit_dialog.dart'; import '../third_screen/contact_form_dialog.dart';
class TransactionListItem extends StatelessWidget { class TransactionListItem extends StatelessWidget {
const TransactionListItem( const TransactionListItem(
...@@ -176,7 +176,7 @@ class TransactionListItem extends StatelessWidget { ...@@ -176,7 +176,7 @@ class TransactionListItem extends StatelessWidget {
showDialog( showDialog(
context: context, context: context,
builder: (BuildContext context) { builder: (BuildContext context) {
return ContactEditDialog( return ContactFormDialog(
contact: newContact, contact: newContact,
onSave: (Contact c) { onSave: (Contact c) {
context.read<ContactsCubit>().updateContact(c); context.read<ContactsCubit>().updateContact(c);
......
...@@ -5,18 +5,23 @@ import '../../../data/models/contact.dart'; ...@@ -5,18 +5,23 @@ import '../../../data/models/contact.dart';
import '../../../g1/g1_helper.dart'; import '../../../g1/g1_helper.dart';
import '../../ui_helpers.dart'; import '../../ui_helpers.dart';
class ContactEditDialog extends StatefulWidget { class ContactFormDialog extends StatefulWidget {
const ContactEditDialog( const ContactFormDialog({
{super.key, required this.contact, required this.onSave}); super.key,
required this.contact,
required this.onSave,
this.isNew = false,
});
final Contact contact; final Contact contact;
final Function(Contact) onSave; final Function(Contact) onSave;
final bool isNew;
@override @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>(); final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
late Contact _updatedContact; late Contact _updatedContact;
...@@ -29,36 +34,53 @@ class _ContactEditDialogState extends State<ContactEditDialog> { ...@@ -29,36 +34,53 @@ class _ContactEditDialogState extends State<ContactEditDialog> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return AlertDialog( return AlertDialog(
title: Text(tr('form_contact_title')), title: Text(
tr(widget.isNew ? 'form_contact_title_add' : 'form_contact_title')),
content: Form( content: Form(
key: _formKey, key: _formKey,
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
Row(mainAxisSize: MainAxisSize.min, children: <Widget>[ if (!widget.isNew)
Flexible( Row(mainAxisSize: MainAxisSize.min, children: <Widget>[
child: TextFormField( Flexible(
// maxLines: 2, child: TextFormField(
initialValue: humanizePubKey(_updatedContact.pubKey), // 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( decoration: InputDecoration(
labelText: tr('form_contact_pub_key'), labelText: tr('form_contact_pub_key'),
), ),
enabled: false, onChanged: (String? value) {
)), _updatedContact = _updatedContact.copyWith(pubKey: value);
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),
), ),
]),
TextFormField( TextFormField(
initialValue: _updatedContact.name, initialValue: _updatedContact.name,
decoration: const InputDecoration(labelText: 'Name'), decoration: InputDecoration(labelText: tr('form_contact_name')),
validator: (String? value) { validator: (String? value) {
if (value == null || value.isEmpty) { if (value == null || value.isEmpty) {
return tr('form_contact_name_validation'); return tr('form_contact_name_validation');
......
...@@ -12,7 +12,7 @@ import '../../../g1/g1_helper.dart'; ...@@ -12,7 +12,7 @@ import '../../../g1/g1_helper.dart';
import '../../contacts_cache.dart'; import '../../contacts_cache.dart';
import '../../ui_helpers.dart'; import '../../ui_helpers.dart';
import '../bottom_widget.dart'; import '../bottom_widget.dart';
import 'contact_edit_dialog.dart'; import 'contact_form_dialog.dart';
class ContactsPage extends StatefulWidget { class ContactsPage extends StatefulWidget {
const ContactsPage({super.key}); const ContactsPage({super.key});
...@@ -134,7 +134,7 @@ class _ContactsPageState extends State<ContactsPage> { ...@@ -134,7 +134,7 @@ class _ContactsPageState extends State<ContactsPage> {
showDialog( showDialog(
context: context, context: context,
builder: (BuildContext context) { builder: (BuildContext context) {
return ContactEditDialog( return ContactFormDialog(
contact: contact, contact: contact,
onSave: (Contact c) { onSave: (Contact c) {
context context
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment