|
|
|
@ -11,6 +11,7 @@ import 'package:immich_mobile/providers/infrastructure/people.provider.dart';
|
|
|
|
import 'package:immich_mobile/utils/debug_print.dart';
|
|
|
|
import 'package:immich_mobile/utils/debug_print.dart';
|
|
|
|
import 'package:immich_mobile/utils/people.utils.dart';
|
|
|
|
import 'package:immich_mobile/utils/people.utils.dart';
|
|
|
|
import 'package:immich_mobile/widgets/common/immich_toast.dart';
|
|
|
|
import 'package:immich_mobile/widgets/common/immich_toast.dart';
|
|
|
|
|
|
|
|
import 'package:logging/logging.dart';
|
|
|
|
|
|
|
|
|
|
|
|
class DriftPersonNameEditForm extends ConsumerStatefulWidget {
|
|
|
|
class DriftPersonNameEditForm extends ConsumerStatefulWidget {
|
|
|
|
final DriftPerson person;
|
|
|
|
final DriftPerson person;
|
|
|
|
@ -72,7 +73,7 @@ class _DriftPersonNameEditFormState extends ConsumerState<DriftPersonNameEditFor
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: Add diacritic filtering? We would need to add a package.
|
|
|
|
// TODO: Add diacritic filtering?
|
|
|
|
void _filterPeople(List<DriftPerson> people, String query) {
|
|
|
|
void _filterPeople(List<DriftPerson> people, String query) {
|
|
|
|
final queryParts = query.toLowerCase().split(' ').where((e) => e.isNotEmpty).toList();
|
|
|
|
final queryParts = query.toLowerCase().split(' ').where((e) => e.isNotEmpty).toList();
|
|
|
|
|
|
|
|
|
|
|
|
@ -80,7 +81,10 @@ class _DriftPersonNameEditFormState extends ConsumerState<DriftPersonNameEditFor
|
|
|
|
List<DriftPerson> containsMatches = [];
|
|
|
|
List<DriftPerson> containsMatches = [];
|
|
|
|
|
|
|
|
|
|
|
|
for (final p in people) {
|
|
|
|
for (final p in people) {
|
|
|
|
|
|
|
|
if (p.id == widget.person.id) continue;
|
|
|
|
|
|
|
|
|
|
|
|
final nameParts = p.name.toLowerCase().split(' ').where((e) => e.isNotEmpty).toList();
|
|
|
|
final nameParts = p.name.toLowerCase().split(' ').where((e) => e.isNotEmpty).toList();
|
|
|
|
|
|
|
|
|
|
|
|
final allStart = queryParts.every((q) => nameParts.any((n) => n.startsWith(q)));
|
|
|
|
final allStart = queryParts.every((q) => nameParts.any((n) => n.startsWith(q)));
|
|
|
|
final allContain = queryParts.every((q) => nameParts.any((n) => n.contains(q)));
|
|
|
|
final allContain = queryParts.every((q) => nameParts.any((n) => n.contains(q)));
|
|
|
|
|
|
|
|
|
|
|
|
@ -94,7 +98,7 @@ class _DriftPersonNameEditFormState extends ConsumerState<DriftPersonNameEditFor
|
|
|
|
|
|
|
|
|
|
|
|
if (!mounted) return;
|
|
|
|
if (!mounted) return;
|
|
|
|
setState(() {
|
|
|
|
setState(() {
|
|
|
|
// TODO: What happens if there are more than 3 matches with the exact same name?
|
|
|
|
// TODO: happens if there are more than 3 matches with the exact same name?
|
|
|
|
_filteredPeople = query.isEmpty ? [] : (startsWithMatches + containsMatches).take(3).toList();
|
|
|
|
_filteredPeople = query.isEmpty ? [] : (startsWithMatches + containsMatches).take(3).toList();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -102,26 +106,28 @@ class _DriftPersonNameEditFormState extends ConsumerState<DriftPersonNameEditFor
|
|
|
|
@override
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
final curatedPeople = ref.watch(driftGetAllPeopleProvider);
|
|
|
|
final curatedPeople = ref.watch(driftGetAllPeopleProvider);
|
|
|
|
|
|
|
|
List<DriftPerson> people = [];
|
|
|
|
|
|
|
|
|
|
|
|
return AlertDialog(
|
|
|
|
return AlertDialog(
|
|
|
|
title: const Text("edit_name", style: TextStyle(fontWeight: FontWeight.bold)).tr(),
|
|
|
|
title: const Text("edit_name", style: TextStyle(fontWeight: FontWeight.bold)).tr(),
|
|
|
|
content: curatedPeople.when(
|
|
|
|
content: SingleChildScrollView(
|
|
|
|
data: (people) {
|
|
|
|
child: Column(
|
|
|
|
return SingleChildScrollView(
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
child: Column(
|
|
|
|
children: [
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
TextFormField(
|
|
|
|
children: [
|
|
|
|
autofocus: true,
|
|
|
|
TextFormField(
|
|
|
|
controller: _formController,
|
|
|
|
autofocus: true,
|
|
|
|
decoration: InputDecoration(
|
|
|
|
controller: _formController,
|
|
|
|
hintText: 'add_a_name'.tr(),
|
|
|
|
decoration: InputDecoration(
|
|
|
|
border: const OutlineInputBorder(borderRadius: BorderRadius.all(Radius.circular(8))),
|
|
|
|
hintText: 'add_a_name'.tr(),
|
|
|
|
),
|
|
|
|
border: const OutlineInputBorder(borderRadius: BorderRadius.all(Radius.circular(8))),
|
|
|
|
onChanged: (value) => _filterPeople(people, value),
|
|
|
|
),
|
|
|
|
onTapOutside: (event) => FocusScope.of(context).unfocus(),
|
|
|
|
onChanged: (value) => _filterPeople(people, value),
|
|
|
|
),
|
|
|
|
onTapOutside: (event) => FocusScope.of(context).unfocus(),
|
|
|
|
curatedPeople.when(
|
|
|
|
),
|
|
|
|
data: (p) {
|
|
|
|
AnimatedSize(
|
|
|
|
people = p;
|
|
|
|
|
|
|
|
return AnimatedSize(
|
|
|
|
duration: const Duration(milliseconds: 200),
|
|
|
|
duration: const Duration(milliseconds: 200),
|
|
|
|
child: SizedBox(
|
|
|
|
child: SizedBox(
|
|
|
|
width: double.infinity,
|
|
|
|
width: double.infinity,
|
|
|
|
@ -158,13 +164,16 @@ class _DriftPersonNameEditFormState extends ConsumerState<DriftPersonNameEditFor
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
],
|
|
|
|
},
|
|
|
|
|
|
|
|
loading: () => const Center(child: CircularProgressIndicator()),
|
|
|
|
|
|
|
|
error: (err, stack) {
|
|
|
|
|
|
|
|
Logger('PersonEditNameModal').warning('Error loading people for name edit modal', err, stack);
|
|
|
|
|
|
|
|
return Center(child: Text('Error loading people for name edit modal: $err'));
|
|
|
|
|
|
|
|
},
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
],
|
|
|
|
},
|
|
|
|
),
|
|
|
|
loading: () => const Center(child: CircularProgressIndicator()),
|
|
|
|
|
|
|
|
error: (err, stack) => Text('Error: $err'),
|
|
|
|
|
|
|
|
),
|
|
|
|
),
|
|
|
|
actions: [
|
|
|
|
actions: [
|
|
|
|
TextButton(
|
|
|
|
TextButton(
|
|
|
|
|