improve viewport performance
This commit is contained in:
@@ -103,6 +103,7 @@ class _AnimatedToolbar extends HookWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
controller.addListener(listener);
|
controller.addListener(listener);
|
||||||
|
listener();
|
||||||
return () => controller.removeListener(listener);
|
return () => controller.removeListener(listener);
|
||||||
}, [onAnimationProgress, toolbarHeight]);
|
}, [onAnimationProgress, toolbarHeight]);
|
||||||
|
|
||||||
@@ -394,43 +395,86 @@ class BrowserScreen extends HookConsumerWidget {
|
|||||||
final findInPageHeight = findInPageVisible
|
final findInPageHeight = findInPageVisible
|
||||||
? FindInPageWidget.findInPageHeight
|
? FindInPageWidget.findInPageHeight
|
||||||
: 0.0;
|
: 0.0;
|
||||||
|
final findInPageHeightPx = (findInPageHeight * pixelRatio).round();
|
||||||
|
|
||||||
// Set up GeckoView dynamic toolbar height
|
final stableToolbarHeight = autoHideTabBar ? bottomAppBarTotalHeight : 0.0;
|
||||||
// This tells GeckoView the maximum toolbar space so it can adjust viewport
|
final stableToolbarHeightPx = (stableToolbarHeight * pixelRatio).round();
|
||||||
final baseToolbarHeight = bottomToolbarVisible
|
|
||||||
? bottomAppBarTotalHeight
|
|
||||||
: 0.0;
|
|
||||||
final totalToolbarHeight = findInPageVisible
|
|
||||||
? baseToolbarHeight + findInPageHeight
|
|
||||||
: baseToolbarHeight;
|
|
||||||
final toolbarHeightPx = (totalToolbarHeight * pixelRatio).round();
|
|
||||||
|
|
||||||
useEffect(() {
|
final keyboardHeightPx = useState<int?>(null);
|
||||||
final lastKeyboardEvent = viewportService.keyboardEvents.valueOrNull;
|
|
||||||
|
|
||||||
if (lastKeyboardEvent == null || !lastKeyboardEvent.isVisible) {
|
|
||||||
unawaited(viewportService.setDynamicToolbarMaxHeight(toolbarHeightPx));
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}, [toolbarHeightPx]);
|
|
||||||
|
|
||||||
// Listen to keyboard visibility changes from native
|
|
||||||
useOnStreamChange(
|
useOnStreamChange(
|
||||||
viewportService.keyboardEvents,
|
viewportService.keyboardEvents,
|
||||||
onData: (event) {
|
onData: (event) {
|
||||||
// When keyboard is visible, use keyboard height for viewport adjustment.
|
if (!event.isAnimating) {
|
||||||
// When hidden, restore normal toolbar height to avoid stale viewport size.
|
final nextKeyboardHeight = event.isVisible ? event.heightPx : null;
|
||||||
final findInPageHeightPx = findInPageVisible
|
if (keyboardHeightPx.value != nextKeyboardHeight) {
|
||||||
? (FindInPageWidget.findInPageHeight * pixelRatio).round()
|
keyboardHeightPx.value = nextKeyboardHeight;
|
||||||
: 0;
|
}
|
||||||
final targetHeightPx = event.isVisible && event.heightPx > 0
|
}
|
||||||
? event.heightPx + findInPageHeightPx
|
|
||||||
: toolbarHeightPx;
|
|
||||||
unawaited(viewportService.setDynamicToolbarMaxHeight(targetHeightPx));
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final keyboardVisible = keyboardHeightPx.value != null;
|
||||||
|
|
||||||
|
final bottomLayoutReservedPx = (!autoHideTabBar && bottomToolbarVisible)
|
||||||
|
? (bottomAppBarTotalHeight * pixelRatio).round()
|
||||||
|
: 0;
|
||||||
|
final keyboardViewportHeightPx = keyboardVisible
|
||||||
|
? math.max(0, keyboardHeightPx.value! - bottomLayoutReservedPx)
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
final effectiveToolbarHeightPx = keyboardVisible
|
||||||
|
? keyboardViewportHeightPx + findInPageHeightPx
|
||||||
|
: stableToolbarHeightPx;
|
||||||
|
|
||||||
|
final lastToolbarMaxHeightPx = useRef<int?>(null);
|
||||||
|
|
||||||
|
useEffect(() {
|
||||||
|
if (lastToolbarMaxHeightPx.value != effectiveToolbarHeightPx) {
|
||||||
|
lastToolbarMaxHeightPx.value = effectiveToolbarHeightPx;
|
||||||
|
unawaited(
|
||||||
|
viewportService.setDynamicToolbarMaxHeight(effectiveToolbarHeightPx),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}, [effectiveToolbarHeightPx]);
|
||||||
|
|
||||||
|
// Track last clipping value to avoid redundant platform channel calls
|
||||||
|
final lastClippingPx = useRef(0);
|
||||||
|
final desiredToolbarClippingPx = useRef(0);
|
||||||
|
|
||||||
|
// Keep clipping state in sync with keyboard and auto-hide states.
|
||||||
|
// While keyboard is visible, do not apply toolbar clipping.
|
||||||
|
useEffect(() {
|
||||||
|
final targetClippingPx = autoHideTabBar && !keyboardVisible
|
||||||
|
? desiredToolbarClippingPx.value
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
if (targetClippingPx != lastClippingPx.value) {
|
||||||
|
lastClippingPx.value = targetClippingPx;
|
||||||
|
unawaited(viewportService.setVerticalClipping(targetClippingPx));
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}, [autoHideTabBar, keyboardVisible]);
|
||||||
|
|
||||||
|
final animationProgressCallback = useCallback((
|
||||||
|
double progress,
|
||||||
|
double heightPx,
|
||||||
|
) {
|
||||||
|
// Clip content from bottom as toolbar hides.
|
||||||
|
// Negative clipping = clip from bottom.
|
||||||
|
final clippingPx = -((1.0 - progress) * heightPx * pixelRatio).round();
|
||||||
|
desiredToolbarClippingPx.value = clippingPx;
|
||||||
|
|
||||||
|
final targetClippingPx = keyboardVisible ? 0 : clippingPx;
|
||||||
|
|
||||||
|
if (targetClippingPx != lastClippingPx.value) {
|
||||||
|
lastClippingPx.value = targetClippingPx;
|
||||||
|
unawaited(viewportService.setVerticalClipping(targetClippingPx));
|
||||||
|
}
|
||||||
|
}, [keyboardVisible, pixelRatio]);
|
||||||
|
|
||||||
// Theme with dynamic snackbar margin to position above bottom toolbar
|
// Theme with dynamic snackbar margin to position above bottom toolbar
|
||||||
final themeData = Theme.of(context).copyWith(
|
final themeData = Theme.of(context).copyWith(
|
||||||
bottomSheetTheme: BottomSheetThemeData(
|
bottomSheetTheme: BottomSheetThemeData(
|
||||||
@@ -509,6 +553,9 @@ class BrowserScreen extends HookConsumerWidget {
|
|||||||
position: TabBarPosition.bottom,
|
position: TabBarPosition.bottom,
|
||||||
visible: bottomToolbarVisible,
|
visible: bottomToolbarVisible,
|
||||||
toolbarHeight: bottomAppBarTotalHeight,
|
toolbarHeight: bottomAppBarTotalHeight,
|
||||||
|
onAnimationProgress: autoHideTabBar
|
||||||
|
? animationProgressCallback
|
||||||
|
: null,
|
||||||
child: _TabBar(
|
child: _TabBar(
|
||||||
tabBarPosition: TabBarPosition.bottom,
|
tabBarPosition: TabBarPosition.bottom,
|
||||||
displayAppBar: displayAppBar,
|
displayAppBar: displayAppBar,
|
||||||
|
|||||||
Reference in New Issue
Block a user