Skip to content

Commit 47e0b6e

Browse files
committed
fix(app): catch if the scroll controller does not have clients
1 parent 878e01d commit 47e0b6e

File tree

1 file changed

+31
-21
lines changed

1 file changed

+31
-21
lines changed

app/lib/common/widgets/scrollable_stack_with_indicator.dart

+31-21
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,7 @@ class ScrollableStackWithIndicator extends HookWidget {
3333
return scrollPosition.pixels >= maxScrollOffset;
3434
}
3535

36-
double? _getRelativeScrollPosition(
37-
GlobalKey contentKey,
38-
ScrollPosition scrollPosition,
39-
) {
36+
double? _getRelativeScrollPosition(ScrollPosition scrollPosition) {
4037
final maxScrollOffset = scrollPosition.maxScrollExtent;
4138
final relativePosition =
4239
1 - (maxScrollOffset - scrollPosition.pixels) / maxScrollOffset;
@@ -53,6 +50,7 @@ class ScrollableStackWithIndicator extends HookWidget {
5350
final scrollbarPadding = rightScrollbarPadding ?? PharMeTheme.smallSpace;
5451
final horizontalPadding = scrollbarPadding + 3 * scrollbarThickness;
5552
final contentKey = GlobalKey();
53+
final failedIndicatorInitializationAttempts = useState(0);
5654
final showScrollIndicatorButton = useState(false);
5755
final scrollIndicatorButtonOpacity = useState<double>(1);
5856
final scrollController = useScrollController(
@@ -61,12 +59,14 @@ class ScrollableStackWithIndicator extends HookWidget {
6159
);
6260

6361
void handleScrolling() {
64-
final hideButton = _scrolledToEnd(scrollController.position) ?? false;
65-
showScrollIndicatorButton.value = !hideButton;
66-
final relativeScrollPosition =
67-
_getRelativeScrollPosition(contentKey, scrollController.position);
68-
if (relativeScrollPosition != null) {
69-
scrollIndicatorButtonOpacity.value = 1 - relativeScrollPosition;
62+
if (scrollController.hasClients) {
63+
final hideButton = _scrolledToEnd(scrollController.position) ?? false;
64+
showScrollIndicatorButton.value = !hideButton;
65+
final relativeScrollPosition =
66+
_getRelativeScrollPosition(scrollController.position);
67+
if (relativeScrollPosition != null) {
68+
scrollIndicatorButtonOpacity.value = 1 - relativeScrollPosition;
69+
}
7070
}
7171
}
7272

@@ -76,11 +76,19 @@ class ScrollableStackWithIndicator extends HookWidget {
7676
}, [scrollController]);
7777

7878
WidgetsBinding.instance.addPostFrameCallback((_) {
79-
final contentScrollable =
80-
_contentScrollable(contentKey, scrollController.position) ?? false;
81-
final scrolledToEnd =
82-
_scrolledToEnd(scrollController.position) ?? false;
83-
showScrollIndicatorButton.value = contentScrollable && !scrolledToEnd;
79+
try {
80+
final contentScrollable =
81+
_contentScrollable(contentKey, scrollController.position);
82+
if (contentScrollable == null) {
83+
failedIndicatorInitializationAttempts.value += 1;
84+
return;
85+
}
86+
final scrolledToEnd =
87+
_scrolledToEnd(scrollController.position) ?? false;
88+
showScrollIndicatorButton.value = contentScrollable && !scrolledToEnd;
89+
} catch (exception) {
90+
failedIndicatorInitializationAttempts.value += 1;
91+
}
8492
});
8593

8694
return Stack(
@@ -130,12 +138,14 @@ class ScrollableStackWithIndicator extends HookWidget {
130138
color: iconColor ?? PharMeTheme.iconColor,
131139
),
132140
onPressed: () async {
133-
await scrollController.animateTo(
134-
scrollController.position.maxScrollExtent,
135-
duration: Duration(milliseconds: 500),
136-
curve: Curves.linearToEaseOut,
137-
);
138-
showScrollIndicatorButton.value = false;
141+
if (scrollController.hasClients) {
142+
await scrollController.animateTo(
143+
scrollController.position.maxScrollExtent,
144+
duration: Duration(milliseconds: 500),
145+
curve: Curves.linearToEaseOut,
146+
);
147+
showScrollIndicatorButton.value = false;
148+
}
139149
},
140150
),
141151
),

0 commit comments

Comments
 (0)