Skip to content

Commit c4ec14a

Browse files
committed
refactor(shared): update HeadlineTileImageTop widget
- Replace custom image loading with Image.network - Remove unused imports and variables - Update category to topic terminology - Modify navigation to use EntityDetailsPageArguments - Remove time ago formatting for now
1 parent ac5a09b commit c4ec14a

File tree

1 file changed

+55
-69
lines changed

1 file changed

+55
-69
lines changed

lib/shared/widgets/headline_tile_image_top.dart

Lines changed: 55 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
import 'package:flutter/material.dart';
2-
import 'package:go_router/go_router.dart'; // Added
3-
import 'package:ht_main/entity_details/models/entity_type.dart';
4-
import 'package:ht_main/entity_details/view/entity_details_page.dart'; // Added for Page Arguments
5-
import 'package:ht_main/l10n/app_localizations.dart';
2+
import 'package:go_router/go_router.dart';
3+
import 'package:ht_main/entity_details/view/entity_details_page.dart';
64
import 'package:ht_main/l10n/l10n.dart';
7-
import 'package:ht_main/router/routes.dart'; // Added
8-
import 'package:ht_main/shared/constants/app_spacing.dart';
9-
import 'package:ht_main/shared/utils/utils.dart'; // Import the new utility
10-
import 'package:ht_shared/ht_shared.dart' show Headline;
11-
// timeago import removed from here, handled by utility
5+
import 'package:ht_main/router/routes.dart';
6+
import 'package:ht_shared/ht_shared.dart';
7+
import 'package:ht_ui_kit/ht_ui_kit.dart';
128

139
/// {@template headline_tile_image_top}
1410
/// A shared widget to display a headline item with a large image at the top.
@@ -34,14 +30,13 @@ class HeadlineTileImageTop extends StatelessWidget {
3430
final Widget? trailing;
3531

3632
/// The type of the entity currently being viewed in detail (e.g., on a category page).
37-
final EntityType? currentContextEntityType;
33+
final ContentType? currentContextEntityType;
3834

3935
/// The ID of the entity currently being viewed in detail.
4036
final String? currentContextEntityId;
4137

4238
@override
4339
Widget build(BuildContext context) {
44-
final l10n = context.l10n;
4540
final theme = Theme.of(context);
4641
final textTheme = theme.textTheme;
4742
final colorScheme = theme.colorScheme;
@@ -61,44 +56,33 @@ class HeadlineTileImageTop extends StatelessWidget {
6156
topLeft: Radius.circular(AppSpacing.xs),
6257
topRight: Radius.circular(AppSpacing.xs),
6358
),
64-
child: headline.imageUrl != null
65-
? Image.network(
66-
headline.imageUrl,
67-
width: double.infinity,
68-
height: 180, // Standard large image height
69-
fit: BoxFit.cover,
70-
loadingBuilder: (context, child, loadingProgress) {
71-
if (loadingProgress == null) return child;
72-
return Container(
73-
width: double.infinity,
74-
height: 180,
75-
color: colorScheme.surfaceContainerHighest,
76-
child: const Center(
77-
child: CircularProgressIndicator(strokeWidth: 2),
78-
),
79-
);
80-
},
81-
errorBuilder: (context, error, stackTrace) => Container(
82-
width: double.infinity,
83-
height: 180,
84-
color: colorScheme.surfaceContainerHighest,
85-
child: Icon(
86-
Icons.broken_image_outlined,
87-
color: colorScheme.onSurfaceVariant,
88-
size: AppSpacing.xxl,
89-
),
90-
),
91-
)
92-
: Container(
93-
width: double.infinity,
94-
height: 180,
95-
color: colorScheme.surfaceContainerHighest,
96-
child: Icon(
97-
Icons.image_not_supported_outlined,
98-
color: colorScheme.onSurfaceVariant,
99-
size: AppSpacing.xxl,
100-
),
59+
child: Image.network(
60+
headline.imageUrl,
61+
width: double.infinity,
62+
height: 180, // Standard large image height
63+
fit: BoxFit.cover,
64+
loadingBuilder: (context, child, loadingProgress) {
65+
if (loadingProgress == null) return child;
66+
return Container(
67+
width: double.infinity,
68+
height: 180,
69+
color: colorScheme.surfaceContainerHighest,
70+
child: const Center(
71+
child: CircularProgressIndicator(strokeWidth: 2),
10172
),
73+
);
74+
},
75+
errorBuilder: (context, error, stackTrace) => Container(
76+
width: double.infinity,
77+
height: 180,
78+
color: colorScheme.surfaceContainerHighest,
79+
child: Icon(
80+
Icons.broken_image_outlined,
81+
color: colorScheme.onSurfaceVariant,
82+
size: AppSpacing.xxl,
83+
),
84+
),
85+
),
10286
),
10387
),
10488
Padding(
@@ -131,7 +115,6 @@ class HeadlineTileImageTop extends StatelessWidget {
131115
const SizedBox(height: AppSpacing.sm),
132116
_HeadlineMetadataRow(
133117
headline: headline,
134-
l10n: l10n,
135118
colorScheme: colorScheme,
136119
textTheme: textTheme,
137120
currentContextEntityType:
@@ -151,23 +134,22 @@ class HeadlineTileImageTop extends StatelessWidget {
151134
class _HeadlineMetadataRow extends StatelessWidget {
152135
const _HeadlineMetadataRow({
153136
required this.headline,
154-
required this.l10n,
155137
required this.colorScheme,
156138
required this.textTheme,
157139
this.currentContextEntityType,
158140
this.currentContextEntityId,
159141
});
160142

161143
final Headline headline;
162-
final AppLocalizations l10n;
163144
final ColorScheme colorScheme;
164145
final TextTheme textTheme;
165-
final EntityType? currentContextEntityType;
146+
final ContentType? currentContextEntityType;
166147
final String? currentContextEntityId;
167148

168149
@override
169150
Widget build(BuildContext context) {
170-
final formattedDate = formatRelativeTime(context, headline.publishedAt);
151+
// TODO(anyone): Use a proper timeago library.
152+
final formattedDate = headline.createdAt.toString();
171153

172154
// Use bodySmall for a reasonable base size, with muted accent color
173155
final metadataTextStyle = textTheme.bodySmall?.copyWith(
@@ -195,34 +177,35 @@ class _HeadlineMetadataRow extends StatelessWidget {
195177
Text(formattedDate, style: metadataTextStyle),
196178
],
197179
),
198-
// Conditionally render Category as Text
199-
if (headline.category?.name != null &&
200-
!(currentContextEntityType == EntityType.category &&
201-
headline.category!.id == currentContextEntityId)) ...[
180+
// Conditionally render Topic as Text
181+
if (headline.topic.name.isNotEmpty &&
182+
!(currentContextEntityType == ContentType.topic &&
183+
headline.topic.id == currentContextEntityId)) ...[
202184
if (formattedDate.isNotEmpty)
203185
Padding(
204186
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.xs),
205187
child: Text('•', style: metadataTextStyle),
206188
),
207189
GestureDetector(
208190
onTap: () {
209-
if (headline.category != null) {
210-
context.push(
211-
Routes.categoryDetails,
212-
extra: EntityDetailsPageArguments(entity: headline.category),
213-
);
214-
}
191+
context.push(
192+
Routes.topicDetails,
193+
extra: EntityDetailsPageArguments(
194+
entity: headline.topic,
195+
contentType: ContentType.topic,
196+
),
197+
);
215198
},
216-
child: Text(headline.category!.name, style: metadataTextStyle),
199+
child: Text(headline.topic.name, style: metadataTextStyle),
217200
),
218201
],
219202
// Conditionally render Source as Text
220-
if (!(currentContextEntityType == EntityType.source &&
203+
if (!(currentContextEntityType == ContentType.source &&
221204
headline.source.id == currentContextEntityId)) ...[
222205
if (formattedDate.isNotEmpty ||
223-
(headline.category?.name != null &&
224-
!(currentContextEntityType == EntityType.category &&
225-
headline.category!.id == currentContextEntityId)))
206+
(headline.topic.name.isNotEmpty &&
207+
!(currentContextEntityType == ContentType.topic &&
208+
headline.topic.id == currentContextEntityId)))
226209
Padding(
227210
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.xs),
228211
child: Text('•', style: metadataTextStyle),
@@ -231,7 +214,10 @@ class _HeadlineMetadataRow extends StatelessWidget {
231214
onTap: () {
232215
context.push(
233216
Routes.sourceDetails,
234-
extra: EntityDetailsPageArguments(entity: headline.source),
217+
extra: EntityDetailsPageArguments(
218+
entity: headline.source,
219+
contentType: ContentType.source,
220+
),
235221
);
236222
},
237223
child: Text(headline.source.name, style: metadataTextStyle),

0 commit comments

Comments
 (0)