Skip to content

Commit 8b7c037

Browse files
committed
refactor(headlines-feed): replace Column with CustomScrollView
- Remove Column widget and replace it with CustomScrollView - Add SliverToBoxAdapter for SavedFiltersBar - Wrap ListView.separated with SliverPadding - This change allows for better scrolling performance and consistency
1 parent caab96a commit 8b7c037

File tree

1 file changed

+87
-87
lines changed

1 file changed

+87
-87
lines changed

lib/headlines-feed/view/headlines_feed_page.dart

Lines changed: 87 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -121,97 +121,97 @@ class _HeadlinesFeedPageState extends State<HeadlinesFeedPage> {
121121
),
122122
),
123123
),
124-
body: Column(
125-
children: [
126-
const Padding(
127-
padding: EdgeInsets.symmetric(horizontal: AppSpacing.md),
128-
child: SavedFiltersBar(),
129-
),
130-
Expanded(
131-
child: BlocBuilder<HeadlinesFeedBloc, HeadlinesFeedState>(
132-
builder: (context, state) {
133-
// Access the AppBloc to check for remoteConfig availability.
134-
final appBlocState = context.watch<AppBloc>().state;
124+
body: BlocBuilder<HeadlinesFeedBloc, HeadlinesFeedState>(
125+
builder: (context, state) {
126+
// Access the AppBloc to check for remoteConfig availability.
127+
final appBlocState = context.watch<AppBloc>().state;
128+
129+
// If remoteConfig is not yet loaded, show a loading indicator.
130+
// This handles the brief period after authentication but before
131+
// the remote config is fetched, preventing null access errors.
132+
if (appBlocState.remoteConfig == null) {
133+
return LoadingStateWidget(
134+
icon: Icons.settings_applications_outlined,
135+
headline: l10n.headlinesFeedLoadingHeadline,
136+
subheadline: l10n.pleaseWait,
137+
);
138+
}
135139

136-
// If remoteConfig is not yet loaded, show a loading indicator.
137-
// This handles the brief period after authentication but before
138-
// the remote config is fetched, preventing null access errors.
139-
if (appBlocState.remoteConfig == null) {
140-
return LoadingStateWidget(
141-
icon: Icons.settings_applications_outlined,
142-
headline: l10n.headlinesFeedLoadingHeadline,
143-
subheadline: l10n.pleaseWait,
144-
);
145-
}
140+
if (state.status == HeadlinesFeedStatus.initial ||
141+
(state.status == HeadlinesFeedStatus.loading &&
142+
state.feedItems.isEmpty)) {
143+
return LoadingStateWidget(
144+
icon: Icons.newspaper,
145+
headline: l10n.headlinesFeedLoadingHeadline,
146+
subheadline: l10n.headlinesFeedLoadingSubheadline,
147+
);
148+
}
146149

147-
if (state.status == HeadlinesFeedStatus.initial ||
148-
(state.status == HeadlinesFeedStatus.loading &&
149-
state.feedItems.isEmpty)) {
150-
return LoadingStateWidget(
151-
icon: Icons.newspaper,
152-
headline: l10n.headlinesFeedLoadingHeadline,
153-
subheadline: l10n.headlinesFeedLoadingSubheadline,
154-
);
155-
}
150+
if (state.status == HeadlinesFeedStatus.failure &&
151+
state.feedItems.isEmpty) {
152+
return FailureStateWidget(
153+
//TODO(fulleni): l10n.
154+
exception:
155+
state.error ??
156+
const UnknownException('Failed to load headlines feed.'),
157+
onRetry: () => context.read<HeadlinesFeedBloc>().add(
158+
HeadlinesFeedRefreshRequested(
159+
adThemeStyle: AdThemeStyle.fromTheme(theme),
160+
),
161+
),
162+
);
163+
}
156164

157-
if (state.status == HeadlinesFeedStatus.failure &&
158-
state.feedItems.isEmpty) {
159-
return FailureStateWidget(
160-
//TODO(fulleni): l10n.
161-
exception:
162-
state.error ??
163-
const UnknownException(
164-
'Failed to load headlines feed.',
165-
),
166-
onRetry: () => context.read<HeadlinesFeedBloc>().add(
167-
HeadlinesFeedRefreshRequested(
165+
if (state.status == HeadlinesFeedStatus.success &&
166+
state.feedItems.isEmpty) {
167+
return Center(
168+
child: Column(
169+
mainAxisAlignment: MainAxisAlignment.center,
170+
children: [
171+
InitialStateWidget(
172+
icon: Icons.search_off,
173+
headline: l10n.headlinesFeedEmptyFilteredHeadline,
174+
subheadline: l10n.headlinesFeedEmptyFilteredSubheadline,
175+
),
176+
const SizedBox(height: AppSpacing.lg),
177+
ElevatedButton(
178+
onPressed: () => context.read<HeadlinesFeedBloc>().add(
179+
HeadlinesFeedFiltersCleared(
168180
adThemeStyle: AdThemeStyle.fromTheme(theme),
169181
),
170182
),
171-
);
172-
}
173-
174-
if (state.status == HeadlinesFeedStatus.success &&
175-
state.feedItems.isEmpty) {
176-
return Center(
177-
child: Column(
178-
mainAxisAlignment: MainAxisAlignment.center,
179-
children: [
180-
InitialStateWidget(
181-
icon: Icons.search_off,
182-
headline: l10n.headlinesFeedEmptyFilteredHeadline,
183-
subheadline:
184-
l10n.headlinesFeedEmptyFilteredSubheadline,
185-
),
186-
const SizedBox(height: AppSpacing.lg),
187-
ElevatedButton(
188-
onPressed: () =>
189-
context.read<HeadlinesFeedBloc>().add(
190-
HeadlinesFeedFiltersCleared(
191-
adThemeStyle: AdThemeStyle.fromTheme(theme),
192-
),
193-
),
194-
child: Text(l10n.headlinesFeedClearFiltersButton),
195-
),
196-
],
197-
),
198-
);
199-
}
183+
child: Text(l10n.headlinesFeedClearFiltersButton),
184+
),
185+
],
186+
),
187+
);
188+
}
200189

201-
return RefreshIndicator(
202-
onRefresh: () async {
203-
context.read<HeadlinesFeedBloc>().add(
204-
HeadlinesFeedRefreshRequested(
205-
adThemeStyle: AdThemeStyle.fromTheme(theme),
206-
),
207-
);
208-
},
209-
child: ListView.separated(
210-
controller: _scrollController,
211-
padding: const EdgeInsets.only(
212-
top: AppSpacing.md,
213-
bottom: AppSpacing.xxl,
190+
return RefreshIndicator(
191+
onRefresh: () async {
192+
context.read<HeadlinesFeedBloc>().add(
193+
HeadlinesFeedRefreshRequested(
194+
adThemeStyle: AdThemeStyle.fromTheme(theme),
195+
),
196+
);
197+
},
198+
child: CustomScrollView(
199+
controller: _scrollController,
200+
slivers: [
201+
const SliverToBoxAdapter(
202+
child: Padding(
203+
padding: EdgeInsets.symmetric(
204+
horizontal: AppSpacing.md,
214205
),
206+
child: SavedFiltersBar(),
207+
),
208+
),
209+
SliverPadding(
210+
padding: const EdgeInsets.only(
211+
top: AppSpacing.md,
212+
bottom: AppSpacing.xxl,
213+
),
214+
sliver: SliverList.separated(
215215
itemCount: state.hasMore
216216
? state.feedItems.length + 1
217217
: state.feedItems.length,
@@ -401,11 +401,11 @@ class _HeadlinesFeedPageState extends State<HeadlinesFeedPage> {
401401
return const SizedBox.shrink();
402402
},
403403
),
404-
);
405-
},
404+
),
405+
],
406406
),
407-
),
408-
],
407+
);
408+
},
409409
),
410410
),
411411
);

0 commit comments

Comments
 (0)