Skip to content

Commit 7372cd8

Browse files
committed
feat(feed_decorators): implement dynamic height for dismissed widget
Refactors `DecoratorDismissedWidget` to have a dynamic height that mirrors the user's selected headline tile style. - The widget now reads `headlineImageStyle` from the `AppBloc` state. - A helper method calculates the appropriate height based on the user's setting, ensuring a seamless UI transition when a decorator is dismissed by preventing layout jank. - This change addresses the issue of the widget having a fixed, hardcoded height.
1 parent 213123c commit 7372cd8

File tree

1 file changed

+29
-4
lines changed

1 file changed

+29
-4
lines changed

lib/feed_decorators/widgets/decorator_dismissed_widget.dart

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,55 @@
1+
import 'package:core/core.dart';
12
import 'package:flutter/material.dart';
3+
import 'package:flutter_bloc/flutter_bloc.dart';
4+
import 'package:flutter_news_app_mobile_client_full_source_code/app/bloc/app_bloc.dart';
25
import 'package:flutter_news_app_mobile_client_full_source_code/l10n/l10n.dart';
36
import 'package:ui_kit/ui_kit.dart';
47

58
/// {@template decorator_dismissed_widget}
69
/// A widget displayed in place of a feed decorator after it has been
710
/// dismissed by the user.
11+
///
12+
/// This widget's height dynamically adjusts to match the user's selected
13+
/// headline tile style to prevent layout shifts in the feed.
814
/// {@endtemplate}
915
class DecoratorDismissedWidget extends StatelessWidget {
1016
/// {@macro decorator_dismissed_widget}
1117
const DecoratorDismissedWidget({super.key});
1218

19+
/// Determines the height of the widget based on the user's feed preference.
20+
///
21+
/// This ensures that when a decorator is dismissed, the placeholder that
22+
/// replaces it has a similar height to the surrounding headline tiles,
23+
/// preventing a jarring layout shift.
24+
double _getDynamicHeight(HeadlineImageStyle imageStyle) {
25+
return switch (imageStyle) {
26+
// Approximate height for a text-only list tile.
27+
HeadlineImageStyle.hidden => 80,
28+
// Approximate height for a list tile with a leading image.
29+
HeadlineImageStyle.smallThumbnail => 100,
30+
// Approximate height for a card with an image on top.
31+
HeadlineImageStyle.largeThumbnail => 280,
32+
};
33+
}
34+
1335
@override
1436
Widget build(BuildContext context) {
1537
final theme = Theme.of(context);
1638
final l10n = AppLocalizationsX(context).l10n;
39+
final headlineImageStyle = context
40+
.watch<AppBloc>()
41+
.state
42+
.headlineImageStyle;
1743

1844
return Card(
1945
margin: const EdgeInsets.symmetric(
2046
horizontal: AppSpacing.lg,
2147
vertical: AppSpacing.md,
2248
),
23-
// TODO(fulleni): size must reflect the hight of the selected headlines feed tile widget.
2449
child: SizedBox(
25-
// This height is an approximation of the CallToActionDecoratorWidget's
26-
// height to ensure minimal layout shift upon dismissal.
27-
height: 140,
50+
// The height is dynamically set to match the current headline tile
51+
// style, ensuring a smooth visual transition upon dismissal.
52+
height: _getDynamicHeight(headlineImageStyle),
2853
child: Center(
2954
child: Text(
3055
l10n.decoratorDismissedConfirmation,

0 commit comments

Comments
 (0)