feat(mobile): person age on photo properties (#16728)

* feat(mobile): person age on photo properties

* switch to using placeholder
This commit is contained in:
Yaros 2025-03-08 23:02:40 +01:00 committed by GitHub
parent 1e127ae3a1
commit 6c5f99c47a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 54 additions and 9 deletions

View File

@ -264,6 +264,7 @@
"exif_bottom_sheet_location_add": "Add a location",
"exif_bottom_sheet_people": "PEOPLE",
"exif_bottom_sheet_person_add_person": "Add name",
"exif_bottom_sheet_person_age": "Age {}",
"experimental_settings_new_asset_list_subtitle": "Work in progress",
"experimental_settings_new_asset_list_title": "Enable experimental photo grid",
"experimental_settings_subtitle": "Use at your own risk!",

View File

@ -8,20 +8,26 @@ class SearchCuratedContent {
/// The label to show associated with this curated object
final String label;
/// The subtitle to show below the label
final String? subtitle;
/// The id to lookup the asset from the server
final String id;
SearchCuratedContent({
required this.label,
required this.id,
this.subtitle,
});
SearchCuratedContent copyWith({
String? label,
String? subtitle,
String? id,
}) {
return SearchCuratedContent(
label: label ?? this.label,
subtitle: subtitle ?? this.subtitle,
id: id ?? this.id,
);
}
@ -29,6 +35,7 @@ class SearchCuratedContent {
Map<String, dynamic> toMap() {
return <String, dynamic>{
'label': label,
'subtitle': subtitle,
'id': id,
};
}
@ -36,6 +43,7 @@ class SearchCuratedContent {
factory SearchCuratedContent.fromMap(Map<String, dynamic> map) {
return SearchCuratedContent(
label: map['label'] as String,
subtitle: map['subtitle'] as String?,
id: map['id'] as String,
);
}
@ -46,13 +54,14 @@ class SearchCuratedContent {
SearchCuratedContent.fromMap(json.decode(source) as Map<String, dynamic>);
@override
String toString() => 'CuratedContent(label: $label, id: $id)';
String toString() =>
'CuratedContent(label: $label, subtitle: $subtitle, id: $id)';
@override
bool operator ==(covariant SearchCuratedContent other) {
if (identical(this, other)) return true;
return other.label == label && other.id == id;
return other.label == label && other.subtitle == subtitle && other.id == id;
}
@override

View File

@ -44,7 +44,19 @@ class PeopleInfo extends ConsumerWidget {
}
final curatedPeople = people
?.map((p) => SearchCuratedContent(id: p.id, label: p.name))
?.map(
(p) => SearchCuratedContent(
id: p.id,
label: p.name,
subtitle: p.birthDate != null
? "exif_bottom_sheet_person_age".tr(
args: [
_calculateAge(p.birthDate!).toString(),
],
)
: null,
),
)
.toList() ??
[];
@ -99,4 +111,17 @@ class PeopleInfo extends ConsumerWidget {
),
);
}
int _calculateAge(DateTime birthDate) {
DateTime today = DateTime.now();
int age = today.year - birthDate.year;
// Check if the birthday has occurred this year
if (today.month < birthDate.month ||
(today.month == birthDate.month && today.day < birthDate.day)) {
age--;
}
return age;
}
}

View File

@ -86,12 +86,22 @@ class CuratedPeopleRow extends StatelessWidget {
).tr(),
);
}
return Text(
person.label,
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
style: context.textTheme.labelLarge,
maxLines: 2,
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
person.label,
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
style: context.textTheme.labelLarge,
maxLines: 2,
),
if (person.subtitle != null)
Text(
person.subtitle!,
textAlign: TextAlign.center,
),
],
);
}
}