use reload button to cancel load if available
This commit is contained in:
+38
-8
@@ -34,6 +34,8 @@ import 'package:weblibre/features/geckoview/domain/repositories/tab.dart';
|
||||
import 'package:weblibre/features/geckoview/features/bookmarks/domain/repositories/bookmarks.dart';
|
||||
import 'package:weblibre/features/geckoview/features/bookmarks/domain/utils/bookmark_tree_utils.dart';
|
||||
import 'package:weblibre/features/geckoview/features/browser/domain/entities/font_size_constants.dart';
|
||||
import 'package:weblibre/features/geckoview/features/browser/features/contextual_toolbar/data/providers/toolbar_button_configs.dart';
|
||||
import 'package:weblibre/features/geckoview/features/browser/features/contextual_toolbar/domain/entities/toolbar_button_id.dart';
|
||||
import 'package:weblibre/features/geckoview/features/browser/features/contextual_toolbar/domain/entities/toolbar_button_spec.dart';
|
||||
import 'package:weblibre/features/geckoview/features/browser/features/contextual_toolbar/presentation/models/contextual_toolbar_scope.dart';
|
||||
import 'package:weblibre/features/geckoview/features/browser/features/contextual_toolbar/presentation/widgets/contextual_bar_buttons.dart';
|
||||
@@ -83,14 +85,31 @@ class ToolbarButtonDefinition {
|
||||
});
|
||||
}
|
||||
|
||||
/// Whether a reload button is currently configured visible in the contextual
|
||||
/// toolbar. Used to decide whether the back button should fall back to acting
|
||||
/// as a stop-loading control (see issue #351).
|
||||
bool _isReloadButtonVisible(WidgetRef ref) {
|
||||
return ref
|
||||
.read(effectiveToolbarButtonConfigsProvider)
|
||||
.value
|
||||
.any(
|
||||
(config) =>
|
||||
config.buttonId == ToolbarButtonId.reload.name && config.isVisible,
|
||||
);
|
||||
}
|
||||
|
||||
final List<ToolbarButtonDefinition> toolbarButtonRegistry = [
|
||||
ToolbarButtonDefinition(
|
||||
spec: backToolbarButtonSpec,
|
||||
label: 'Back',
|
||||
icon: Icons.arrow_back,
|
||||
isPrimaryAvailable: (scope, ref) =>
|
||||
scope.tabState?.historyState.canGoBack == true ||
|
||||
scope.tabState?.isLoading == true,
|
||||
isPrimaryAvailable: (scope, ref) {
|
||||
final canGoBack = scope.tabState?.historyState.canGoBack == true;
|
||||
final isLoading = scope.tabState?.isLoading == true;
|
||||
// The back button only doubles as a stop-loading control when no
|
||||
// dedicated reload button is present to take over that role.
|
||||
return canGoBack || (isLoading && !_isReloadButtonVisible(ref));
|
||||
},
|
||||
longPressActions: ['History Menu (Previous pages)'],
|
||||
builder: (scope, context, ref) {
|
||||
if (scope.isPreview) {
|
||||
@@ -104,6 +123,7 @@ final List<ToolbarButtonDefinition> toolbarButtonRegistry = [
|
||||
return NavigateBackButton(
|
||||
selectedTabId: scope.selectedTabId,
|
||||
isLoading: scope.tabState?.isLoading ?? false,
|
||||
stopLoadingFallback: !_isReloadButtonVisible(ref),
|
||||
);
|
||||
},
|
||||
),
|
||||
@@ -616,6 +636,7 @@ class _ReloadToolbarButton extends HookConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final menuController = useMemoized(MenuController.new);
|
||||
final isLoading = scope.tabState?.isLoading ?? false;
|
||||
|
||||
return MenuAnchor(
|
||||
controller: menuController,
|
||||
@@ -640,12 +661,21 @@ class _ReloadToolbarButton extends HookConsumerWidget {
|
||||
: () async {
|
||||
final tabId = scope.selectedTabId;
|
||||
if (tabId != null) {
|
||||
await ref
|
||||
.read(tabSessionProvider(tabId: tabId).notifier)
|
||||
.reload();
|
||||
final controller = ref.read(
|
||||
tabSessionProvider(tabId: tabId).notifier,
|
||||
);
|
||||
// While loading the button acts as a stop control; otherwise
|
||||
// it reloads the page.
|
||||
if (isLoading) {
|
||||
await controller.stopLoading();
|
||||
} else {
|
||||
await controller.reload();
|
||||
}
|
||||
}
|
||||
},
|
||||
onLongPress: scope.isPreview
|
||||
// Hard Refresh is meaningless mid-load, so disable the long-press menu
|
||||
// while the stop action is active.
|
||||
onLongPress: (scope.isPreview || isLoading)
|
||||
? null
|
||||
: () {
|
||||
if (menuController.isOpen) {
|
||||
@@ -654,7 +684,7 @@ class _ReloadToolbarButton extends HookConsumerWidget {
|
||||
menuController.open();
|
||||
}
|
||||
},
|
||||
icon: const Icon(Icons.refresh),
|
||||
icon: Icon(isLoading ? Icons.close : Icons.refresh),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
+19
-4
@@ -52,21 +52,30 @@ class NavigateBackButtonView extends StatelessWidget {
|
||||
super.key,
|
||||
required this.canGoBack,
|
||||
required this.isLoading,
|
||||
this.stopLoadingFallback = true,
|
||||
this.onPressed,
|
||||
this.onLongPress,
|
||||
});
|
||||
|
||||
final bool canGoBack;
|
||||
final bool isLoading;
|
||||
|
||||
/// When `true` (default), the button doubles as a stop-loading control while
|
||||
/// [isLoading] (shows a close icon, taps cancel the load). When `false` it
|
||||
/// stays a plain back button even during loading — used when a dedicated
|
||||
/// reload/stop button is present elsewhere in the toolbar.
|
||||
final bool stopLoadingFallback;
|
||||
final VoidCallback? onPressed;
|
||||
final VoidCallback? onLongPress;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final showStop = isLoading && stopLoadingFallback;
|
||||
|
||||
return IconButton(
|
||||
onPressed: (canGoBack || isLoading) ? onPressed : null,
|
||||
onLongPress: (canGoBack && !isLoading) ? onLongPress : null,
|
||||
icon: isLoading ? const Icon(Icons.close) : const Icon(Icons.arrow_back),
|
||||
onPressed: (canGoBack || showStop) ? onPressed : null,
|
||||
onLongPress: (canGoBack && !showStop) ? onLongPress : null,
|
||||
icon: showStop ? const Icon(Icons.close) : const Icon(Icons.arrow_back),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -118,18 +127,23 @@ class NavigateBackButton extends HookConsumerWidget {
|
||||
super.key,
|
||||
required this.selectedTabId,
|
||||
required this.isLoading,
|
||||
this.stopLoadingFallback = true,
|
||||
this.menuControllerToClose,
|
||||
this.canGoBack = true,
|
||||
});
|
||||
|
||||
final String? selectedTabId;
|
||||
final bool isLoading;
|
||||
|
||||
/// See [NavigateBackButtonView.stopLoadingFallback].
|
||||
final bool stopLoadingFallback;
|
||||
final MenuController? menuControllerToClose;
|
||||
final bool canGoBack;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final historyMenuController = useMenuController();
|
||||
final showStop = isLoading && stopLoadingFallback;
|
||||
|
||||
return HistoryMenu(
|
||||
selectedTabId: selectedTabId,
|
||||
@@ -138,6 +152,7 @@ class NavigateBackButton extends HookConsumerWidget {
|
||||
child: NavigateBackButtonView(
|
||||
canGoBack: canGoBack,
|
||||
isLoading: isLoading,
|
||||
stopLoadingFallback: stopLoadingFallback,
|
||||
onPressed: () async {
|
||||
final controller = ref.read(
|
||||
tabSessionProvider(tabId: selectedTabId).notifier,
|
||||
@@ -149,7 +164,7 @@ class NavigateBackButton extends HookConsumerWidget {
|
||||
),
|
||||
);
|
||||
|
||||
if (isLoading) {
|
||||
if (showStop) {
|
||||
await controller.stopLoading();
|
||||
} else if (isReaderActive) {
|
||||
await ref
|
||||
|
||||
Reference in New Issue
Block a user