improve tabbar dismiss logic; fix #157

This commit is contained in:
Fabian Freund
2026-02-05 16:40:36 +01:00
parent c7f9d6ec12
commit d17c6e542f
4 changed files with 32 additions and 18 deletions
@@ -21,7 +21,7 @@ import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'tab_bar_dismissable.g.dart'; part 'tab_bar_dismissable.g.dart';
@Riverpod() @Riverpod(keepAlive: true)
class TabBarDismissableController extends _$TabBarDismissableController { class TabBarDismissableController extends _$TabBarDismissableController {
void show() { void show() {
state = false; state = false;
@@ -21,7 +21,7 @@ final class TabBarDismissableControllerProvider
argument: null, argument: null,
retry: null, retry: null,
name: r'tabBarDismissableControllerProvider', name: r'tabBarDismissableControllerProvider',
isAutoDispose: true, isAutoDispose: false,
dependencies: null, dependencies: null,
$allTransitiveDependencies: null, $allTransitiveDependencies: null,
); );
@@ -43,7 +43,7 @@ final class TabBarDismissableControllerProvider
} }
String _$tabBarDismissableControllerHash() => String _$tabBarDismissableControllerHash() =>
r'2bb0055f5525a21982ba3d7cb6443bcad823b64f'; r'e0c2f700ccebc35bc8029370cdebd63e98bf95e1';
abstract class _$TabBarDismissableController extends $Notifier<bool> { abstract class _$TabBarDismissableController extends $Notifier<bool> {
bool build(); bool build();
@@ -211,6 +211,11 @@ class _TabBar extends HookConsumerWidget {
if (!ref.read(generalSettingsWithDefaultsProvider).autoHideTabBar) { if (!ref.read(generalSettingsWithDefaultsProvider).autoHideTabBar) {
return; return;
} }
// Don't apply auto-hide when toolbar is manually dismissed
if (ref.read(tabBarDismissableControllerProvider)) {
return;
}
final diff = event.dy; final diff = event.dy;
if (diff < 0) { if (diff < 0) {
if (diffAcc.value > 0) { if (diffAcc.value > 0) {
@@ -18,7 +18,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart'; import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart'; import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
@@ -211,8 +214,6 @@ class BrowserTabBar extends HookConsumerWidget {
final dragStartPosition = useRef(Offset.zero); final dragStartPosition = useRef(Offset.zero);
final toolbarHeight = useMemoized(() => getToolbarHeight());
return GestureDetector( return GestureDetector(
// Tap handling moved to AppBarTitle for split icon/title behavior // Tap handling moved to AppBarTitle for split icon/title behavior
onHorizontalDragStart: (details) { onHorizontalDragStart: (details) {
@@ -245,19 +246,27 @@ class BrowserTabBar extends HookConsumerWidget {
} }
} }
} }
} else if (distance.dx.abs() < 15) { }
// Swipe direction for dismiss depends on toolbar position: },
// - Bottom bar: swipe down to dismiss (distance.dy negative or small positive) onVerticalDragStart: (details) {
// - Top bar: swipe up to dismiss (distance.dy positive or small negative) dragStartPosition.value = details.globalPosition;
final dismissThreshold = toolbarHeight * 0.75; },
final shouldDismiss = switch (tabBarPosition) { onVerticalDragEnd: (details) {
TabBarPosition.bottom => distance.dy < dismissThreshold, final distance = dragStartPosition.value - details.globalPosition;
TabBarPosition.top => distance.dy > -dismissThreshold,
}; // Swipe direction for dismiss depends on toolbar position:
if (shouldDismiss && // - Bottom bar: swipe down to dismiss (positive distance.dy)
ref.read(bottomSheetControllerProvider) == null) { // - Top bar: swipe up to dismiss (negative distance.dy)
ref.read(tabBarDismissableControllerProvider.notifier).dismiss(); const dismissThreshold = kToolbarHeight * 0.5;
} final shouldDismiss = switch (tabBarPosition) {
TabBarPosition.bottom =>
distance.dy.isNegative && distance.dy.abs() > dismissThreshold,
TabBarPosition.top =>
!distance.dy.isNegative && distance.dy.abs() > dismissThreshold,
};
if (shouldDismiss && ref.read(bottomSheetControllerProvider) == null) {
unawaited(HapticFeedback.lightImpact());
ref.read(tabBarDismissableControllerProvider.notifier).dismiss();
} }
}, },
child: Column( child: Column(