1
0
mirror of https://github.com/immich-app/immich.git synced 2024-12-19 00:32:49 +02:00
immich/mobile/lib/modules/search/ui/curated_people_row.dart
Emanuel Bennici ba12d92af3
feat(mobile): Add people list to exit bottom sheet (#6717)
* feat(mobile): Define constants as 'const'

* feat(mobile): Add people list to asset bottom sheet

Add a list of people per asset in the exif bottom sheet, like on the
web.

Currently the list of people is loaded by making a request each time to
the server. This is the MVP approach.
In the future, the people information can be synced like we're doing
with the assets.

* styling

---------

Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2024-03-06 11:15:54 -05:00

108 lines
3.4 KiB
Dart

import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/search/models/curated_content.dart';
import 'package:immich_mobile/modules/search/ui/thumbnail_with_info.dart';
import 'package:immich_mobile/shared/models/store.dart';
import 'package:immich_mobile/utils/image_url_builder.dart';
class CuratedPeopleRow extends StatelessWidget {
final List<CuratedContent> content;
/// Callback with the content and the index when tapped
final Function(CuratedContent, int)? onTap;
final Function(CuratedContent, int)? onNameTap;
const CuratedPeopleRow({
super.key,
required this.content,
this.onTap,
required this.onNameTap,
});
@override
Widget build(BuildContext context) {
const imageSize = 85.0;
// Guard empty [content]
if (content.isEmpty) {
// Return empty thumbnail
return Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: SizedBox(
width: imageSize,
height: imageSize,
child: ThumbnailWithInfo(
textInfo: '',
onTap: () {},
),
),
),
);
}
return ListView.builder(
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
final person = content[index];
final headers = {
"x-immich-user-token": Store.get(StoreKey.accessToken),
};
return Padding(
padding: const EdgeInsets.only(right: 18.0),
child: SizedBox(
width: imageSize,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
GestureDetector(
onTap: () => onTap?.call(person, index),
child: SizedBox(
height: imageSize,
child: Material(
shape: const CircleBorder(side: BorderSide.none),
elevation: 3,
child: CircleAvatar(
maxRadius: imageSize / 2,
backgroundImage: NetworkImage(
getFaceThumbnailUrl(person.id),
headers: headers,
),
),
),
),
),
if (person.label == "")
GestureDetector(
onTap: () => onNameTap?.call(person, index),
child: Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Text(
"Add name",
style: context.textTheme.labelLarge?.copyWith(
color: context.primaryColor,
),
),
),
)
else
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Text(
person.label,
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
style: context.textTheme.labelLarge,
),
),
],
),
),
);
},
itemCount: content.length,
);
}
}