@@ -10,13 +10,14 @@ import 'package:ht_main/headlines-search/bloc/headlines_search_bloc.dart';
10
10
import 'package:ht_main/headlines-search/models/search_model_type.dart' ;
11
11
// Import new item widgets
12
12
import 'package:ht_main/headlines-search/widgets/category_item_widget.dart' ;
13
- import 'package:ht_main/headlines-search/widgets/country_item_widget.dart' ;
13
+ // import 'package:ht_main/headlines-search/widgets/country_item_widget.dart'; // Removed
14
14
import 'package:ht_main/headlines-search/widgets/source_item_widget.dart' ;
15
15
import 'package:ht_main/l10n/l10n.dart' ;
16
16
import 'package:ht_main/router/routes.dart' ;
17
17
import 'package:ht_main/shared/constants/app_spacing.dart' ;
18
18
import 'package:ht_main/shared/shared.dart' ; // Imports new headline tiles
19
- import 'package:ht_shared/ht_shared.dart' ;
19
+ // Adjusted imports to only include what's necessary after country removal
20
+ import 'package:ht_shared/ht_shared.dart' show Category, Headline, Source, HeadlineImageStyle, SearchModelType;
20
21
21
22
/// Page widget responsible for providing the BLoC for the headlines search feature.
22
23
class HeadlinesSearchPage extends StatelessWidget {
@@ -58,8 +59,10 @@ class _HeadlinesSearchViewState extends State<_HeadlinesSearchView> {
58
59
_showClearButton = _textController.text.isNotEmpty;
59
60
});
60
61
});
61
- // Set initial model type in BLoC if not already set (e.g. on first load)
62
- // Though BLoC state now defaults, this ensures UI and BLoC are in sync.
62
+ // Ensure _selectedModelType is valid (it should be, as .country is removed from enum)
63
+ if (! SearchModelType .values.contains (_selectedModelType)) {
64
+ _selectedModelType = SearchModelType .headline;
65
+ }
63
66
context.read <HeadlinesSearchBloc >().add (
64
67
HeadlinesSearchModelTypeChanged (_selectedModelType),
65
68
);
@@ -102,21 +105,36 @@ class _HeadlinesSearchViewState extends State<_HeadlinesSearchView> {
102
105
final colorScheme = theme.colorScheme;
103
106
final appBarTheme = theme.appBarTheme;
104
107
108
+ // Use all values from SearchModelType as .country is already removed from the enum itself
109
+ final availableSearchModelTypes = SearchModelType .values.toList ();
110
+
111
+ // Ensure _selectedModelType is still valid if it somehow was .country
112
+ // (though this shouldn't happen if initState logic is correct and enum is updated)
113
+ if (! availableSearchModelTypes.contains (_selectedModelType)) {
114
+ _selectedModelType = SearchModelType .headline;
115
+ WidgetsBinding .instance.addPostFrameCallback ((_) {
116
+ if (mounted) {
117
+ context.read <HeadlinesSearchBloc >().add (
118
+ HeadlinesSearchModelTypeChanged (_selectedModelType),
119
+ );
120
+ }
121
+ });
122
+ }
123
+
105
124
return Scaffold (
106
125
appBar: AppBar (
107
- // Removed leading and leadingWidth
108
- titleSpacing: AppSpacing .paddingSmall, // Adjust title spacing if needed
126
+ titleSpacing: AppSpacing .paddingSmall,
109
127
title: Row (
110
128
children: [
111
129
SizedBox (
112
- width: 140 , // Constrain dropdown width
130
+ width: 140 ,
113
131
child: DropdownButtonFormField <SearchModelType >(
114
132
value: _selectedModelType,
115
133
decoration: const InputDecoration (
116
134
border: InputBorder .none,
117
135
contentPadding: EdgeInsets .symmetric (
118
- horizontal: AppSpacing .xs, // Minimal horizontal padding
119
- vertical: AppSpacing .xs, // Reduce vertical padding
136
+ horizontal: AppSpacing .xs,
137
+ vertical: AppSpacing .xs,
120
138
),
121
139
),
122
140
style: theme.textTheme.titleMedium? .copyWith (
@@ -129,30 +147,30 @@ class _HeadlinesSearchViewState extends State<_HeadlinesSearchView> {
129
147
Icons .arrow_drop_down,
130
148
color: appBarTheme.iconTheme? .color ?? colorScheme.onSurface,
131
149
),
132
- items:
133
- SearchModelType .values. map (( SearchModelType type) {
134
- String displayLocalizedName;
135
- switch (type) {
136
- case SearchModelType .headline:
137
- displayLocalizedName = l10n.searchModelTypeHeadline;
138
- case SearchModelType .category :
139
- displayLocalizedName = l10n.searchModelTypeCategory;
140
- case SearchModelType .source :
141
- displayLocalizedName = l10n.searchModelTypeSource ;
142
- case SearchModelType .country :
143
- displayLocalizedName = l10n.searchModelTypeCountry ;
144
- }
145
- return DropdownMenuItem < SearchModelType >(
146
- value : type,
147
- child : Text (
148
- displayLocalizedName,
149
- style : theme.textTheme.titleMedium ? . copyWith (
150
- // Consistent style
151
- color: colorScheme.onSurface,
152
- ),
153
- ),
154
- );
155
- }).toList (),
150
+ items: availableSearchModelTypes. map (( SearchModelType type) {
151
+ String displayLocalizedName;
152
+ // The switch is now exhaustive as SearchModelType.country is removed from the enum
153
+ switch (type) {
154
+ case SearchModelType .headline:
155
+ displayLocalizedName = l10n.searchModelTypeHeadline;
156
+ break ;
157
+ case SearchModelType .category :
158
+ displayLocalizedName = l10n.searchModelTypeCategory;
159
+ break ;
160
+ case SearchModelType .source :
161
+ displayLocalizedName = l10n.searchModelTypeSource ;
162
+ break ;
163
+ }
164
+ return DropdownMenuItem < SearchModelType >(
165
+ value : type,
166
+ child : Text (
167
+ displayLocalizedName,
168
+ style: theme.textTheme.titleMedium ? . copyWith (
169
+ color: colorScheme.onSurface,
170
+ ),
171
+ ),
172
+ );
173
+ }).toList (),
156
174
onChanged: (SearchModelType ? newValue) {
157
175
if (newValue != null ) {
158
176
setState (() {
@@ -165,9 +183,7 @@ class _HeadlinesSearchViewState extends State<_HeadlinesSearchView> {
165
183
},
166
184
),
167
185
),
168
- const SizedBox (
169
- width: AppSpacing .sm,
170
- ), // Spacing between dropdown and textfield
186
+ const SizedBox (width: AppSpacing .sm),
171
187
Expanded (
172
188
child: TextField (
173
189
controller: _textController,
@@ -184,9 +200,7 @@ class _HeadlinesSearchViewState extends State<_HeadlinesSearchView> {
184
200
fillColor: colorScheme.surface.withAlpha (26 ),
185
201
contentPadding: const EdgeInsets .symmetric (
186
202
horizontal: AppSpacing .paddingMedium,
187
- vertical:
188
- AppSpacing .paddingSmall +
189
- 3 , // Fine-tune vertical padding for alignment
203
+ vertical: AppSpacing .paddingSmall + 3 ,
190
204
),
191
205
suffixIcon:
192
206
_showClearButton
@@ -218,16 +232,13 @@ class _HeadlinesSearchViewState extends State<_HeadlinesSearchView> {
218
232
builder: (context, state) {
219
233
return switch (state) {
220
234
HeadlinesSearchInitial () => InitialStateWidget (
221
- icon: Icons .search, // Changed icon
222
- headline: l10n.searchPageInitialHeadline, // Use new generic key
223
- subheadline:
224
- l10n.searchPageInitialSubheadline, // Use new generic key
235
+ icon: Icons .search,
236
+ headline: l10n.searchPageInitialHeadline,
237
+ subheadline: l10n.searchPageInitialSubheadline,
225
238
),
226
- // Use more generic loading text or existing keys
227
239
HeadlinesSearchLoading () => InitialStateWidget (
228
240
icon: Icons .manage_search,
229
- headline:
230
- l10n.headlinesFeedLoadingHeadline, // Re-use feed loading
241
+ headline: l10n.headlinesFeedLoadingHeadline,
231
242
subheadline:
232
243
'Searching ${state .selectedModelType .displayName .toLowerCase ()}...' ,
233
244
),
@@ -255,24 +266,19 @@ class _HeadlinesSearchViewState extends State<_HeadlinesSearchView> {
255
266
)
256
267
: ListView .separated (
257
268
controller: _scrollController,
258
- padding: const EdgeInsets .all (
259
- AppSpacing .paddingMedium,
260
- ), // Add overall padding
269
+ padding: const EdgeInsets .all (AppSpacing .paddingMedium),
261
270
itemCount: hasMore ? results.length + 1 : results.length,
262
271
separatorBuilder:
263
- (context, index) => const SizedBox (
264
- height: AppSpacing .md,
265
- ), // Add separator
272
+ (context, index) => const SizedBox (height: AppSpacing .md),
266
273
itemBuilder: (context, index) {
267
274
if (index >= results.length) {
268
275
return const Padding (
269
- padding: EdgeInsets .symmetric (
270
- vertical: AppSpacing .lg,
271
- ), // Adjusted padding for loader
276
+ padding: EdgeInsets .symmetric (vertical: AppSpacing .lg),
272
277
child: Center (child: CircularProgressIndicator ()),
273
278
);
274
279
}
275
280
final item = results[index];
281
+ // The switch is now exhaustive for the remaining SearchModelType values
276
282
switch (resultsModelType) {
277
283
case SearchModelType .headline:
278
284
final headline = item as Headline ;
@@ -321,8 +327,6 @@ class _HeadlinesSearchViewState extends State<_HeadlinesSearchView> {
321
327
return CategoryItemWidget (category: item as Category );
322
328
case SearchModelType .source:
323
329
return SourceItemWidget (source: item as Source );
324
- case SearchModelType .country:
325
- return CountryItemWidget (country: item as Country );
326
330
}
327
331
},
328
332
),
@@ -339,7 +343,6 @@ class _HeadlinesSearchViewState extends State<_HeadlinesSearchView> {
339
343
HeadlinesSearchFetchRequested (searchTerm: lastSearchTerm),
340
344
),
341
345
),
342
- // Add default case for exhaustiveness
343
346
_ => const SizedBox .shrink (),
344
347
};
345
348
},
@@ -351,15 +354,14 @@ class _HeadlinesSearchViewState extends State<_HeadlinesSearchView> {
351
354
SearchModelType modelType,
352
355
AppLocalizations l10n,
353
356
) {
357
+ // The switch is now exhaustive for the remaining SearchModelType values
354
358
switch (modelType) {
355
359
case SearchModelType .headline:
356
360
return l10n.searchHintTextHeadline;
357
361
case SearchModelType .category:
358
362
return l10n.searchHintTextCategory;
359
363
case SearchModelType .source:
360
364
return l10n.searchHintTextSource;
361
- case SearchModelType .country:
362
- return l10n.searchHintTextCountry;
363
365
}
364
366
}
365
367
}
0 commit comments