Files
yanting/lib/features/shared/report_card_widget.dart
T

88 lines
2.7 KiB
Dart

import 'package:flutter/material.dart';
import '../../data/models/models.dart';
import '../../theme/wise_tokens.dart';
import '../../widgets/app_card.dart';
import '../../widgets/badges.dart';
class ReportCardWidget extends StatelessWidget {
const ReportCardWidget({
required this.report,
required this.onTap,
this.hero = false,
this.onInstitutionTap,
this.onPlayTap,
super.key,
});
final ReportCardModel report;
final VoidCallback onTap;
final bool hero;
final VoidCallback? onInstitutionTap;
final VoidCallback? onPlayTap;
@override
Widget build(BuildContext context) {
final child = Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Wrap(
spacing: WiseSpacing.x2,
runSpacing: WiseSpacing.x2,
children: [
AppBadge(text: report.interpretationLabel, kind: BadgeKind.brand),
if (report.hasAudio)
const AppBadge(text: '音频', icon: Icons.graphic_eq, kind: BadgeKind.audio),
if (report.sourceTier.isNotEmpty)
AppBadge(text: report.sourceTier, icon: Icons.verified_outlined, kind: BadgeKind.tier),
for (final topic in report.topics.take(3)) AppBadge(text: topic),
],
),
const SizedBox(height: WiseSpacing.x3),
Text(
report.titleCn,
maxLines: hero ? 3 : 2,
overflow: TextOverflow.ellipsis,
style: hero
? Theme.of(context).textTheme.titleLarge
: Theme.of(context).textTheme.titleMedium,
),
if (report.oneLiner.isNotEmpty) ...[
const SizedBox(height: WiseSpacing.x2),
Text(
report.oneLiner,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.bodyMedium,
),
],
const SizedBox(height: WiseSpacing.x3),
Row(
children: [
Expanded(
child: InkWell(
onTap: onInstitutionTap,
child: Text(
'${report.institution.nameCn}${report.releasedAt == null ? '' : ' · ${formatDate(report.releasedAt)}'}',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.bodySmall,
),
),
),
if (report.hasAudio)
TextButton.icon(
onPressed: onPlayTap,
icon: const Icon(Icons.play_circle_outline, size: 18),
label: const Text('听研报'),
),
],
),
],
);
return hero
? HeroReportCard(onTap: onTap, child: child)
: AppCard(onTap: onTap, child: child);
}
}