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

Sorted contacts

parent a597e9ac
No related branches found
No related tags found
No related merge requests found
......@@ -232,5 +232,8 @@
"issueCreatedSuccessfully": "An issue has been created with your feedback. Bookmark the issue link to track its progress. Thanks!",
"viewIssue": "View Issue",
"issueCreationErrorTitle": "Error Creating an Issue",
"issueCreationErrorMessage": "There was an error trying to create an issue with your feedback."
"issueCreationErrorMessage": "There was an error trying to create an issue with your feedback.",
"contacts_sort_by_date": "Sort by date",
"contacts_sort_by_name": "Sort by name",
"payment_error_no_pass": "Incorrect passwords"
}
......@@ -238,5 +238,8 @@
"issueCreatedSuccessfully": "Una incidencia ha sido creada con tu problema. Guarda el enlace de la incidencia para seguir su progreso. ¡Gracias!",
"viewIssue": "Ver la incidencia",
"issueCreationErrorTitle": "Error al crear la incidencia",
"issueCreationErrorMessage": "Ocurrió un error al intentar crear una incidencia con el problema que describes."
"issueCreationErrorMessage": "Ocurrió un error al intentar crear una incidencia con el problema que describes.",
"contacts_sort_by_date": "Ordenar por fecha",
"contacts_sort_by_name": "Ordenar por nombre",
"payment_error_no_pass": "Contraseñas incorrectas"
}
......@@ -4,6 +4,7 @@ import 'package:hydrated_bloc/hydrated_bloc.dart';
import '../../g1/g1_helper.dart';
import '../../ui/ui_helpers.dart';
import 'contact.dart';
import 'contact_sort_type.dart';
import 'contact_state.dart';
class ContactsCubit extends HydratedCubit<ContactsState> {
......@@ -24,9 +25,21 @@ class ContactsCubit extends HydratedCubit<ContactsState> {
void addContact(Contact contact) {
final Contact? nFound = _find(contact);
if (nFound == null) {
final List<Contact> updatedContacts = List<Contact>.from(state.contacts)
..add(contact);
List<Contact> updatedFilteredContacts;
if (state.order == ContactsSortType.alpha) {
updatedFilteredContacts = List<Contact>.from(state.filteredContacts)
..add(contact);
sortContactList(updatedFilteredContacts);
} else {
updatedFilteredContacts = updatedContacts;
}
emit(state.copyWith(
contacts: <Contact>[...state.contacts, contact],
filteredContacts: <Contact>[...state.filteredContacts, contact],
contacts: updatedContacts,
filteredContacts: updatedFilteredContacts,
));
}
}
......@@ -93,6 +106,24 @@ class ContactsCubit extends HydratedCubit<ContactsState> {
emit(state.copyWith(filteredContacts: contacts));
}
ContactsSortType get order => state.order;
void sortContacts(ContactsSortType sortOrder) {
List<Contact> sortedContacts = List<Contact>.from(state.contacts);
if (sortOrder == ContactsSortType.alpha) {
sortContactList(sortedContacts);
} else if (sortOrder == ContactsSortType.date) {
sortedContacts = List<Contact>.from(state.contacts);
}
emit(state.copyWith(filteredContacts: sortedContacts, order: sortOrder));
}
void sortContactList(List<Contact> sortedContacts) {
sortedContacts.sort((Contact a, Contact b) => a.title.compareTo(b.title));
}
List<Contact> search(String initialQuery) {
final String query = normalizeQuery(initialQuery);
if (query.isEmpty) {
......
enum ContactsSortType { date, alpha }
......@@ -2,24 +2,30 @@ import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'contact.dart';
import 'contact_sort_type.dart';
@immutable
class ContactsState extends Equatable {
const ContactsState(
{this.contacts = const <Contact>[],
this.filteredContacts = const <Contact>[]});
this.filteredContacts = const <Contact>[],
this.order = ContactsSortType.date});
final List<Contact> contacts;
final List<Contact> filteredContacts;
final ContactsSortType order;
@override
List<Object?> get props => <Object>[contacts, filteredContacts];
List<Object?> get props => <Object>[contacts, filteredContacts, order];
ContactsState copyWith(
{List<Contact>? contacts, List<Contact>? filteredContacts}) {
{List<Contact>? contacts,
List<Contact>? filteredContacts,
ContactsSortType? order}) {
return ContactsState(
contacts: contacts ?? this.contacts,
filteredContacts: filteredContacts ?? this.filteredContacts);
filteredContacts: filteredContacts ?? this.filteredContacts,
order: order ?? this.order);
}
@override
......
......@@ -7,6 +7,7 @@ import 'package:share_plus/share_plus.dart';
import '../../../data/models/bottom_nav_cubit.dart';
import '../../../data/models/contact.dart';
import '../../../data/models/contact_cubit.dart';
import '../../../data/models/contact_sort_type.dart';
import '../../../data/models/payment_cubit.dart';
import '../../../g1/g1_helper.dart';
import '../../contacts_cache.dart';
......@@ -44,16 +45,64 @@ class _ContactsPageState extends State<ContactsPage> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
TextField(
controller: _searchController,
decoration: InputDecoration(
hintText: tr('search_contacts'),
border: const OutlineInputBorder(),
),
onChanged: (String query) {
context.read<ContactsCubit>().filterContacts(query);
},
),
Container(
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.background),
child: Row(children: <Widget>[
Expanded(
child: TextField(
controller: _searchController,
decoration: InputDecoration(
hintText: tr('search_contacts'),
border: const OutlineInputBorder(),
),
onChanged: (String query) {
context.read<ContactsCubit>().filterContacts(query);
})),
PopupMenuButton<ContactsSortType>(
icon: const Icon(Icons.sort),
onSelected: (ContactsSortType result) {
context.read<ContactsCubit>().sortContacts(result);
},
itemBuilder: (BuildContext context) {
final ContactsSortType currentOrder =
context.read<ContactsCubit>().state.order;
return <PopupMenuEntry<ContactsSortType>>[
PopupMenuItem<ContactsSortType>(
value: ContactsSortType.date,
child: ListTile(
leading: Icon(
Icons.date_range,
color: currentOrder == ContactsSortType.date
? Colors.blue
: null,
),
title: Text(tr('contacts_sort_by_date')),
trailing: currentOrder == ContactsSortType.date
? const Icon(Icons.check)
: null,
),
),
PopupMenuItem<ContactsSortType>(
value: ContactsSortType.alpha,
child: ListTile(
leading: Icon(
Icons.sort_by_alpha,
color: currentOrder == ContactsSortType.alpha
? Colors.blue
: null,
),
title: Text(tr('contacts_sort_by_name')),
trailing: currentOrder == ContactsSortType.alpha
? const Icon(Icons.check)
: null,
),
),
];
},
)
])),
const SizedBox(height: 20),
if (cubit.state.filteredContacts.isEmpty)
const NoElements(text: 'no_contacts')
......@@ -66,7 +115,6 @@ class _ContactsPageState extends State<ContactsPage> {
return Slidable(
// Specify a key if the Slidable is dismissible.
key: ValueKey<int>(index),
// The start action pane is the one at the left or the top side.
startActionPane: ActionPane(
// A motion is a widget used to control how the pane animates.
......
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