Files
sm-emby-share/lib/features/detail/widgets/tmdb_cast_section.dart
T

72 lines
1.9 KiB
Dart
Raw Normal View History

2026-07-14 11:11:36 +08:00
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import '../../../core/contracts/tmdb.dart';
import '../../../providers/person_items_provider.dart';
import '../../../shared/mappers/tmdb_image_url.dart';
import '../../../shared/widgets/cast_scroller.dart';
import '../../../shared/widgets/section_header.dart';
class TmdbCastSection extends ConsumerWidget {
final List<TmdbCastMember> cast;
final String imageBaseUrl;
final Widget? leading;
const TmdbCastSection({
super.key,
required this.cast,
required this.imageBaseUrl,
this.leading,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
if (cast.isEmpty) return const SizedBox.shrink();
final entries = cast.map((member) {
return CastEntry(
name: member.name,
subtitle: member.character,
imageUrl: TmdbImageUrl.profile(imageBaseUrl, member.profilePath),
onTap: () => _openPerson(context, ref, member.name),
);
}).toList();
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (leading != null) leading!,
const Padding(
padding: EdgeInsets.fromLTRB(0, 16, 0, 4),
child: SectionHeader(label: '演职人员'),
),
CastScroller(entries: entries),
],
);
}
Future<void> _openPerson(
BuildContext context,
WidgetRef ref,
String name,
) async {
final messenger = ScaffoldMessenger.maybeOf(context);
String? personId;
try {
personId = await ref.read(embyPersonIdByNameProvider(name).future);
} catch (_) {
personId = null;
}
if (!context.mounted) return;
if (personId != null && personId.isNotEmpty) {
context.push('/person/$personId');
} else {
messenger?.showSnackBar(SnackBar(content: Text('未在媒体库中找到「$name」的作品')));
}
}
}