setting to show close button on new/edit tab screen
This commit is contained in:
+19
-1
@@ -22,6 +22,7 @@ import 'dart:async';
|
||||
import 'package:fading_scroll/fading_scroll.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:weblibre/core/design/app_colors.dart';
|
||||
import 'package:weblibre/core/routing/routes.dart';
|
||||
@@ -627,6 +628,12 @@ class SearchScreen extends HookConsumerWidget {
|
||||
};
|
||||
}
|
||||
|
||||
// Whether to surface an in-app close button so the page can be dismissed
|
||||
// without a system back button/gesture (opt-in, e.g. for e-ink devices).
|
||||
// Only meaningful when there is a route to pop back to.
|
||||
final showCloseButton =
|
||||
context.canPop() && settings.showSearchCloseButton;
|
||||
|
||||
return Scaffold(
|
||||
body: SafeArea(
|
||||
child: Form(
|
||||
@@ -638,11 +645,22 @@ class SearchScreen extends HookConsumerWidget {
|
||||
floating: true,
|
||||
pinned: true,
|
||||
automaticallyImplyLeading: false,
|
||||
leading: showCloseButton
|
||||
? IconButton(
|
||||
tooltip: 'Close',
|
||||
icon: const Icon(Icons.close),
|
||||
onPressed: () => context.pop(),
|
||||
)
|
||||
: null,
|
||||
backgroundColor: colorScheme.surface,
|
||||
scrolledUnderElevation: 0,
|
||||
shadowColor: Colors.transparent,
|
||||
surfaceTintColor: Colors.transparent,
|
||||
toolbarHeight: isEditMode ? 0 : kToolbarHeight,
|
||||
// Collapse the toolbar in edit mode (no tab-type switcher), but
|
||||
// keep it when the close button needs somewhere to render.
|
||||
toolbarHeight: (isEditMode && !showCloseButton)
|
||||
? 0
|
||||
: kToolbarHeight,
|
||||
titleSpacing: 0.0,
|
||||
title: isEditMode
|
||||
? null
|
||||
|
||||
@@ -76,6 +76,21 @@ const List<SettingsSectionDefinition> generalSettingsSections = [
|
||||
keywords: ['dialogs', 'bottom sheets', 'overlay'],
|
||||
child: _ShowModalBarrierTile(),
|
||||
),
|
||||
SettingsEntryDefinition(
|
||||
title: 'Show Close Button',
|
||||
subtitle: 'Add a button to dismiss the search / new-tab page without '
|
||||
'a back gesture',
|
||||
keywords: [
|
||||
'back',
|
||||
'close',
|
||||
'dismiss',
|
||||
'e-ink',
|
||||
'eink',
|
||||
'accessibility',
|
||||
'new tab',
|
||||
],
|
||||
child: _ShowSearchCloseButtonTile(),
|
||||
),
|
||||
],
|
||||
),
|
||||
SettingsSectionDefinition(
|
||||
@@ -282,6 +297,37 @@ class _ShowModalBarrierTile extends HookConsumerWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class _ShowSearchCloseButtonTile extends HookConsumerWidget {
|
||||
const _ShowSearchCloseButtonTile();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final showSearchCloseButton = ref.watch(
|
||||
generalSettingsWithDefaultsProvider.select(
|
||||
(s) => s.showSearchCloseButton,
|
||||
),
|
||||
);
|
||||
|
||||
return SwitchListTile.adaptive(
|
||||
title: const Text('Show Close Button'),
|
||||
subtitle: const Text(
|
||||
'Add a button to dismiss the search / new-tab page without a back '
|
||||
'gesture, useful on devices without a back button',
|
||||
),
|
||||
secondary: const Icon(Icons.close),
|
||||
value: showSearchCloseButton,
|
||||
onChanged: (value) async {
|
||||
await ref
|
||||
.read(saveGeneralSettingsControllerProvider.notifier)
|
||||
.save(
|
||||
(currentSettings) =>
|
||||
currentSettings.copyWith.showSearchCloseButton(value),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _PureBlackTile extends HookConsumerWidget {
|
||||
const _PureBlackTile();
|
||||
|
||||
|
||||
@@ -91,6 +91,11 @@ class GeneralSettings with FastEquatable {
|
||||
final bool enableLocalAiFeatures;
|
||||
final bool showContainerUi;
|
||||
final bool showIsolatedTabUi;
|
||||
|
||||
/// Whether the search / new-tab page shows a leading close button so it can
|
||||
/// be dismissed without a system back button or back gesture (e.g. on e-ink
|
||||
/// devices). Defaults to false. Only shown when the route can be popped.
|
||||
final bool showSearchCloseButton;
|
||||
@JsonKey(name: 'defaultCreateTabType')
|
||||
final TabType storedDefaultCreateTabType;
|
||||
final TabDirection tabListDirection;
|
||||
@@ -164,6 +169,7 @@ class GeneralSettings with FastEquatable {
|
||||
required this.enableLocalAiFeatures,
|
||||
required this.showContainerUi,
|
||||
required this.showIsolatedTabUi,
|
||||
required this.showSearchCloseButton,
|
||||
required this.storedDefaultCreateTabType,
|
||||
required this.tabListDirection,
|
||||
required this.tabBarDirection,
|
||||
@@ -225,6 +231,7 @@ class GeneralSettings with FastEquatable {
|
||||
bool? enableLocalAiFeatures,
|
||||
bool? showContainerUi,
|
||||
bool? showIsolatedTabUi,
|
||||
bool? showSearchCloseButton,
|
||||
TabType? storedDefaultCreateTabType,
|
||||
TabDirection? tabListDirection,
|
||||
TabDirection? tabBarDirection,
|
||||
@@ -283,6 +290,7 @@ class GeneralSettings with FastEquatable {
|
||||
enableLocalAiFeatures = enableLocalAiFeatures ?? true,
|
||||
showContainerUi = showContainerUi ?? true,
|
||||
showIsolatedTabUi = showIsolatedTabUi ?? true,
|
||||
showSearchCloseButton = showSearchCloseButton ?? false,
|
||||
storedDefaultCreateTabType =
|
||||
storedDefaultCreateTabType ?? TabType.regular,
|
||||
tabListDirection = tabListDirection ?? TabDirection.newestFirst,
|
||||
@@ -406,6 +414,7 @@ class GeneralSettings with FastEquatable {
|
||||
enableLocalAiFeatures,
|
||||
showContainerUi,
|
||||
showIsolatedTabUi,
|
||||
showSearchCloseButton,
|
||||
storedDefaultCreateTabType,
|
||||
tabListDirection,
|
||||
tabBarDirection,
|
||||
|
||||
@@ -39,6 +39,8 @@ abstract class _$GeneralSettingsCWProxy {
|
||||
|
||||
GeneralSettings showIsolatedTabUi(bool showIsolatedTabUi);
|
||||
|
||||
GeneralSettings showSearchCloseButton(bool showSearchCloseButton);
|
||||
|
||||
GeneralSettings storedDefaultCreateTabType(
|
||||
TabType storedDefaultCreateTabType,
|
||||
);
|
||||
@@ -167,6 +169,7 @@ abstract class _$GeneralSettingsCWProxy {
|
||||
bool enableLocalAiFeatures,
|
||||
bool showContainerUi,
|
||||
bool showIsolatedTabUi,
|
||||
bool showSearchCloseButton,
|
||||
TabType storedDefaultCreateTabType,
|
||||
TabDirection tabListDirection,
|
||||
TabDirection tabBarDirection,
|
||||
@@ -279,6 +282,10 @@ class _$GeneralSettingsCWProxyImpl implements _$GeneralSettingsCWProxy {
|
||||
GeneralSettings showIsolatedTabUi(bool showIsolatedTabUi) =>
|
||||
call(showIsolatedTabUi: showIsolatedTabUi);
|
||||
|
||||
@override
|
||||
GeneralSettings showSearchCloseButton(bool showSearchCloseButton) =>
|
||||
call(showSearchCloseButton: showSearchCloseButton);
|
||||
|
||||
@override
|
||||
GeneralSettings storedDefaultCreateTabType(
|
||||
TabType storedDefaultCreateTabType,
|
||||
@@ -490,6 +497,7 @@ class _$GeneralSettingsCWProxyImpl implements _$GeneralSettingsCWProxy {
|
||||
Object? enableLocalAiFeatures = const $CopyWithPlaceholder(),
|
||||
Object? showContainerUi = const $CopyWithPlaceholder(),
|
||||
Object? showIsolatedTabUi = const $CopyWithPlaceholder(),
|
||||
Object? showSearchCloseButton = const $CopyWithPlaceholder(),
|
||||
Object? storedDefaultCreateTabType = const $CopyWithPlaceholder(),
|
||||
Object? tabListDirection = const $CopyWithPlaceholder(),
|
||||
Object? tabBarDirection = const $CopyWithPlaceholder(),
|
||||
@@ -616,6 +624,12 @@ class _$GeneralSettingsCWProxyImpl implements _$GeneralSettingsCWProxy {
|
||||
? _value.showIsolatedTabUi
|
||||
// ignore: cast_nullable_to_non_nullable
|
||||
: showIsolatedTabUi as bool,
|
||||
showSearchCloseButton:
|
||||
showSearchCloseButton == const $CopyWithPlaceholder() ||
|
||||
showSearchCloseButton == null
|
||||
? _value.showSearchCloseButton
|
||||
// ignore: cast_nullable_to_non_nullable
|
||||
: showSearchCloseButton as bool,
|
||||
storedDefaultCreateTabType:
|
||||
storedDefaultCreateTabType == const $CopyWithPlaceholder() ||
|
||||
storedDefaultCreateTabType == null
|
||||
@@ -916,6 +930,7 @@ GeneralSettings _$GeneralSettingsFromJson(
|
||||
enableLocalAiFeatures: json['enableLocalAiFeatures'] as bool?,
|
||||
showContainerUi: json['showContainerUi'] as bool?,
|
||||
showIsolatedTabUi: json['showIsolatedTabUi'] as bool?,
|
||||
showSearchCloseButton: json['showSearchCloseButton'] as bool?,
|
||||
storedDefaultCreateTabType: $enumDecodeNullable(
|
||||
_$TabTypeEnumMap,
|
||||
json['defaultCreateTabType'],
|
||||
@@ -1029,6 +1044,7 @@ Map<String, dynamic> _$GeneralSettingsToJson(
|
||||
'enableLocalAiFeatures': instance.enableLocalAiFeatures,
|
||||
'showContainerUi': instance.showContainerUi,
|
||||
'showIsolatedTabUi': instance.showIsolatedTabUi,
|
||||
'showSearchCloseButton': instance.showSearchCloseButton,
|
||||
'defaultCreateTabType':
|
||||
_$TabTypeEnumMap[instance.storedDefaultCreateTabType]!,
|
||||
'tabListDirection': _$TabDirectionEnumMap[instance.tabListDirection]!,
|
||||
|
||||
@@ -269,6 +269,10 @@ class GeneralSettingsRepository extends _$GeneralSettingsRepository {
|
||||
DriftSqlType.bool,
|
||||
db.typeMapping,
|
||||
),
|
||||
'showSearchCloseButton': settings['showSearchCloseButton']?.readAs(
|
||||
DriftSqlType.bool,
|
||||
db.typeMapping,
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ final class GeneralSettingsRepositoryProvider
|
||||
}
|
||||
|
||||
String _$generalSettingsRepositoryHash() =>
|
||||
r'5036124c086e35c0e4616a0fd3b2276adb66dd5f';
|
||||
r'6cf0832a8497c94a813e06556c048a1010be74e1';
|
||||
|
||||
abstract class _$GeneralSettingsRepository
|
||||
extends $StreamNotifier<GeneralSettings> {
|
||||
|
||||
Reference in New Issue
Block a user