Skip to content

Commit 93b90d0

Browse files
committed
feat: Display category and country in headlines
- Added category metadata to headline items - Added country metadata with flag - Added repositories to app
1 parent 9fab90a commit 93b90d0

File tree

3 files changed

+77
-0
lines changed

3 files changed

+77
-0
lines changed

lib/app/view/app.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,38 @@ import 'package:flutter/material.dart';
77
import 'package:flutter_bloc/flutter_bloc.dart';
88
import 'package:go_router/go_router.dart';
99
import 'package:ht_authentication_repository/ht_authentication_repository.dart';
10+
import 'package:ht_categories_repository/ht_categories_repository.dart';
11+
import 'package:ht_countries_repository/ht_countries_repository.dart';
1012
import 'package:ht_headlines_repository/ht_headlines_repository.dart';
1113
import 'package:ht_kv_storage_service/ht_kv_storage_service.dart';
1214
import 'package:ht_main/app/bloc/app_bloc.dart';
1315
import 'package:ht_main/authentication/bloc/authentication_bloc.dart';
1416
import 'package:ht_main/l10n/l10n.dart';
1517
import 'package:ht_main/router/router.dart';
1618
import 'package:ht_main/shared/theme/app_theme.dart';
19+
import 'package:ht_sources_repository/ht_sources_repository.dart';
1720

1821
class App extends StatelessWidget {
1922
const App({
2023
required HtHeadlinesRepository htHeadlinesRepository,
2124
required HtAuthenticationRepository htAuthenticationRepository,
25+
required HtCategoriesRepository htCategoriesRepository,
26+
required HtCountriesRepository htCountriesRepository,
27+
required HtSourcesRepository htSourcesRepository,
2228
required HtKVStorageService kvStorageService,
2329
super.key,
2430
}) : _htHeadlinesRepository = htHeadlinesRepository,
2531
_htAuthenticationRepository = htAuthenticationRepository,
32+
_htCategoriesRepository = htCategoriesRepository,
33+
_htCountriesRepository = htCountriesRepository,
34+
_htSourcesRepository = htSourcesRepository,
2635
_kvStorageService = kvStorageService;
2736

2837
final HtHeadlinesRepository _htHeadlinesRepository;
2938
final HtAuthenticationRepository _htAuthenticationRepository;
39+
final HtCategoriesRepository _htCategoriesRepository;
40+
final HtCountriesRepository _htCountriesRepository;
41+
final HtSourcesRepository _htSourcesRepository;
3042
final HtKVStorageService _kvStorageService;
3143

3244
@override
@@ -35,6 +47,9 @@ class App extends StatelessWidget {
3547
providers: [
3648
RepositoryProvider.value(value: _htHeadlinesRepository),
3749
RepositoryProvider.value(value: _htAuthenticationRepository),
50+
RepositoryProvider.value(value: _htCategoriesRepository),
51+
RepositoryProvider.value(value: _htCountriesRepository),
52+
RepositoryProvider.value(value: _htSourcesRepository),
3853
RepositoryProvider.value(value: _kvStorageService),
3954
],
4055
// Use MultiBlocProvider to provide both AppBloc and AuthenticationBloc

lib/headlines-feed/view/headlines_feed_page.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
//
2+
// ignore_for_file: lines_longer_than_80_chars
3+
14
import 'package:flutter/material.dart';
25
import 'package:flutter_bloc/flutter_bloc.dart';
36
import 'package:go_router/go_router.dart';

lib/headlines-feed/widgets/headline_item_widget.dart

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,16 @@ class HeadlineItemWidget extends StatelessWidget {
129129
icon: Icons.access_time_outlined,
130130
text: _dateFormatter.format(headline.publishedAt!),
131131
),
132+
if (headline.category != null)
133+
_MetadataItem(
134+
icon: Icons.category_outlined,
135+
text: headline.category!.name,
136+
),
137+
if (headline.eventCountry != null)
138+
_CountryMetadataItem(
139+
flagUrl: headline.eventCountry!.flagUrl,
140+
countryName: headline.eventCountry!.name,
141+
),
132142
],
133143
),
134144
],
@@ -142,6 +152,55 @@ class HeadlineItemWidget extends StatelessWidget {
142152
}
143153
}
144154

155+
/// Small helper widget for displaying country metadata with a flag avatar.
156+
class _CountryMetadataItem extends StatelessWidget {
157+
const _CountryMetadataItem({
158+
required this.flagUrl,
159+
required this.countryName,
160+
});
161+
162+
final String flagUrl;
163+
final String countryName;
164+
165+
@override
166+
Widget build(BuildContext context) {
167+
final textTheme = Theme.of(context).textTheme;
168+
final colorScheme = Theme.of(context).colorScheme;
169+
const avatarRadius = 7.0; // Small radius for the flag
170+
171+
return Row(
172+
mainAxisSize: MainAxisSize.min, // Take only needed space
173+
children: [
174+
CircleAvatar(
175+
radius: avatarRadius,
176+
backgroundColor: Colors.transparent, // Avoid background color clash
177+
backgroundImage: NetworkImage(flagUrl),
178+
// Optional: Add error handling for the image
179+
onBackgroundImageError: (exception, stackTrace) {
180+
// Log error or display placeholder
181+
debugPrint('Error loading flag image: $exception');
182+
},
183+
// Placeholder in case of error or while loading
184+
child: Icon(
185+
Icons.flag_circle_outlined,
186+
size: avatarRadius * 2,
187+
color: colorScheme.onSurfaceVariant,
188+
),
189+
),
190+
const SizedBox(width: AppSpacing.xs),
191+
Text(
192+
countryName,
193+
style: textTheme.labelSmall?.copyWith(
194+
color: colorScheme.onSurfaceVariant, // Subtle color
195+
),
196+
maxLines: 1,
197+
overflow: TextOverflow.ellipsis,
198+
),
199+
],
200+
);
201+
}
202+
}
203+
145204
/// Small helper widget for displaying metadata with an icon.
146205
class _MetadataItem extends StatelessWidget {
147206
const _MetadataItem({required this.icon, required this.text});

0 commit comments

Comments
 (0)