automatic find in page for search results
This commit is contained in:
@@ -9,6 +9,7 @@ import 'package:weblibre/core/logger.dart';
|
||||
import 'package:weblibre/core/providers/router.dart';
|
||||
import 'package:weblibre/core/routing/routes.dart';
|
||||
import 'package:weblibre/features/bangs/domain/providers/bangs.dart';
|
||||
import 'package:weblibre/features/geckoview/domain/providers/selected_tab.dart';
|
||||
import 'package:weblibre/features/geckoview/domain/providers/tab_state.dart';
|
||||
import 'package:weblibre/features/geckoview/domain/repositories/tab.dart';
|
||||
import 'package:weblibre/features/geckoview/features/find_in_page/presentation/controllers/find_in_page.dart';
|
||||
@@ -50,9 +51,12 @@ GeckoSelectionActionService selectionActionService(Ref ref) {
|
||||
}
|
||||
}),
|
||||
FindInPageAction((text) async {
|
||||
await ref
|
||||
.read(findInPageControllerProvider.notifier)
|
||||
.findAll(text: text);
|
||||
final tabId = ref.read(selectedTabProvider);
|
||||
if (tabId != null) {
|
||||
await ref
|
||||
.read(findInPageControllerProvider(tabId).notifier)
|
||||
.findAll(text: text);
|
||||
}
|
||||
}),
|
||||
ShareAction((text) async {
|
||||
await SharePlus.instance.share(ShareParams(text: text));
|
||||
|
||||
@@ -7,7 +7,7 @@ part of 'providers.dart';
|
||||
// **************************************************************************
|
||||
|
||||
String _$selectionActionServiceHash() =>
|
||||
r'a3682b3f97d9798aadbca3be882d5be74085b762';
|
||||
r'ab6aeb105020a16ed24911acd73ba8553e5b3905';
|
||||
|
||||
/// See also [selectionActionService].
|
||||
@ProviderFor(selectionActionService)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:fast_equatable/fast_equatable.dart';
|
||||
import 'package:nullability/nullability.dart';
|
||||
import 'package:riverpod/riverpod.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:weblibre/features/bangs/data/models/bang_data.dart';
|
||||
@@ -98,9 +99,16 @@ EquatableValue<List<TabEntity>> seamlessFilteredTabEntities(
|
||||
.watch(
|
||||
tabSearchRepositoryProvider(searchPartition).select(
|
||||
(value) => EquatableValue(
|
||||
value.valueOrNull
|
||||
?.map((tab) => SingleTabEntity(tabId: tab.id))
|
||||
.toList(),
|
||||
value.valueOrNull.mapNotNull(
|
||||
(result) => result.results
|
||||
.map(
|
||||
(tab) => SearchResultTabEntity(
|
||||
tabId: tab.id,
|
||||
searchQuery: result.query,
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
@@ -109,7 +117,7 @@ EquatableValue<List<TabEntity>> seamlessFilteredTabEntities(
|
||||
final availableTabs = ref.watch(
|
||||
availableTabIdsProvider(containerFilter).select(
|
||||
(value) => EquatableValue(
|
||||
value.value.map((tab) => SingleTabEntity(tabId: tab)).toList(),
|
||||
value.value.map((tab) => DefaultTabEntity(tabId: tab)).toList(),
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -148,7 +156,13 @@ EquatableValue<List<TabEntity>> seamlessFilteredTabEntities(
|
||||
}
|
||||
|
||||
return EquatableValue(
|
||||
tabSearchResults.where((tab) => availableTabs.value.contains(tab)).toList(),
|
||||
tabSearchResults
|
||||
.where(
|
||||
(tab) => availableTabs.value.any(
|
||||
(available) => available.tabId == tab.tabId,
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -181,6 +195,7 @@ EquatableValue<List<TabPreview>> seamlessFilteredTabPreviews(
|
||||
url: state.url,
|
||||
highlightedUrl: null,
|
||||
content: null,
|
||||
sourceSearchQuery: null,
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
@@ -188,7 +203,7 @@ EquatableValue<List<TabPreview>> seamlessFilteredTabPreviews(
|
||||
}
|
||||
|
||||
return EquatableValue(
|
||||
tabSearchResults
|
||||
tabSearchResults.results
|
||||
.where((tab) => availableTabStates.value.containsKey(tab.id))
|
||||
.map((tab) {
|
||||
return TabPreview(
|
||||
@@ -198,6 +213,7 @@ EquatableValue<List<TabPreview>> seamlessFilteredTabPreviews(
|
||||
url: tab.cleanUrl ?? availableTabStates.value[tab.id]!.url,
|
||||
highlightedUrl: tab.url,
|
||||
content: tab.extractedContent ?? tab.fullContent,
|
||||
sourceSearchQuery: tabSearchResults.query,
|
||||
);
|
||||
})
|
||||
.whereType<TabPreview>()
|
||||
|
||||
@@ -283,7 +283,7 @@ class _AvailableTabStatesProviderElement
|
||||
}
|
||||
|
||||
String _$seamlessFilteredTabEntitiesHash() =>
|
||||
r'0ef5c14f3fa018e3417e097759817bc871be3e0d';
|
||||
r'2cd698d4e7c9d9cda9e17abbf9a99e512425e4cd';
|
||||
|
||||
/// See also [seamlessFilteredTabEntities].
|
||||
@ProviderFor(seamlessFilteredTabEntities)
|
||||
@@ -456,7 +456,7 @@ class _SeamlessFilteredTabEntitiesProviderElement
|
||||
}
|
||||
|
||||
String _$seamlessFilteredTabPreviewsHash() =>
|
||||
r'c59c2819eda4f132e1a0f5f7784ddb3b5ceec817';
|
||||
r'c50a2d0f9f3ba2bc3db7c96e74d9acdcac2e84e4';
|
||||
|
||||
/// See also [seamlessFilteredTabPreviews].
|
||||
@ProviderFor(seamlessFilteredTabPreviews)
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ part of 'tree_view.dart';
|
||||
// **************************************************************************
|
||||
|
||||
String _$treeViewControllerHash() =>
|
||||
r'53da9cc3cc89eab2fee4a3aaf4feccc5ecbfeb20';
|
||||
r'1fac2a133d369e3bd3f8f75cdd2d0c862a6ab942';
|
||||
|
||||
/// See also [TreeViewController].
|
||||
@ProviderFor(TreeViewController)
|
||||
|
||||
@@ -172,6 +172,7 @@ class TabTreeDialog extends HookConsumerWidget {
|
||||
.read(bottomSheetControllerProvider.notifier)
|
||||
.dismiss();
|
||||
},
|
||||
sourceSearchQuery: null,
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
@@ -12,6 +12,7 @@ import 'package:weblibre/extensions/media_query.dart';
|
||||
import 'package:weblibre/features/geckoview/domain/controllers/bottom_sheet.dart';
|
||||
import 'package:weblibre/features/geckoview/domain/controllers/overlay.dart';
|
||||
import 'package:weblibre/features/geckoview/domain/providers.dart';
|
||||
import 'package:weblibre/features/geckoview/domain/providers/selected_tab.dart';
|
||||
import 'package:weblibre/features/geckoview/domain/providers/tab_list.dart';
|
||||
import 'package:weblibre/features/geckoview/domain/providers/tab_session.dart';
|
||||
import 'package:weblibre/features/geckoview/domain/providers/tab_state.dart';
|
||||
@@ -311,7 +312,12 @@ class _BrowserView extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
|
||||
return FindInPageWidget(padding: value);
|
||||
final tabId = ref.watch(selectedTabProvider);
|
||||
if (tabId == null) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
return FindInPageWidget(tabId: tabId, padding: value);
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
+6
-1
@@ -286,7 +286,12 @@ class BrowserBottomAppBar extends HookConsumerWidget {
|
||||
if (selectedTabId != null)
|
||||
MenuItemButton(
|
||||
onPressed: () {
|
||||
ref.read(findInPageControllerProvider.notifier).show();
|
||||
final tabId = ref.read(selectedTabProvider);
|
||||
if (tabId != null) {
|
||||
ref
|
||||
.read(findInPageControllerProvider(tabId).notifier)
|
||||
.show();
|
||||
}
|
||||
},
|
||||
leadingIcon: const Icon(Icons.search),
|
||||
child: const Text('Find in page'),
|
||||
|
||||
+6
-1
@@ -314,13 +314,18 @@ class ViewTabsSheetWidget extends HookConsumerWidget {
|
||||
|
||||
final tabs = useMemoized(() {
|
||||
return filteredTabIds.value
|
||||
.whereType<SingleTabEntity>()
|
||||
.where((entity) => entity is! TabTreeEntity)
|
||||
.mapIndexed((index, entity) {
|
||||
final child = Consumer(
|
||||
child: SingleTabPreview(
|
||||
tabId: entity.tabId,
|
||||
activeTabId: activeTab,
|
||||
onClose: onClose,
|
||||
sourceSearchQuery: switch (entity) {
|
||||
DefaultTabEntity() => null,
|
||||
SearchResultTabEntity() => entity.searchQuery,
|
||||
TabTreeEntity() => throw UnimplementedError(),
|
||||
},
|
||||
),
|
||||
builder: (context, ref, child) {
|
||||
final dragData = ref.watch(
|
||||
|
||||
@@ -10,6 +10,8 @@ import 'package:weblibre/features/geckoview/domain/entities/states/tab.dart';
|
||||
import 'package:weblibre/features/geckoview/domain/providers/tab_state.dart';
|
||||
import 'package:weblibre/features/geckoview/domain/repositories/tab.dart';
|
||||
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_icon.dart';
|
||||
import 'package:weblibre/features/geckoview/features/find_in_page/domain/entities/find_in_page_state.dart';
|
||||
import 'package:weblibre/features/geckoview/features/find_in_page/presentation/controllers/find_in_page.dart';
|
||||
import 'package:weblibre/features/geckoview/features/tabs/data/entities/tab_entity.dart';
|
||||
import 'package:weblibre/features/geckoview/features/tabs/domain/providers.dart';
|
||||
import 'package:weblibre/features/geckoview/features/tabs/domain/repositories/tab.dart';
|
||||
@@ -194,6 +196,7 @@ class TabPreview extends HookWidget {
|
||||
class SingleTabPreview extends HookConsumerWidget {
|
||||
final String tabId;
|
||||
final String? activeTabId;
|
||||
final String? sourceSearchQuery;
|
||||
|
||||
final void Function() onClose;
|
||||
|
||||
@@ -201,6 +204,7 @@ class SingleTabPreview extends HookConsumerWidget {
|
||||
required this.tabId,
|
||||
required this.activeTabId,
|
||||
required this.onClose,
|
||||
required this.sourceSearchQuery,
|
||||
}) : super(key: ValueKey(tabId));
|
||||
|
||||
@override
|
||||
@@ -219,6 +223,13 @@ class SingleTabPreview extends HookConsumerWidget {
|
||||
//Close first to avoid rebuilds
|
||||
onClose();
|
||||
await ref.read(tabRepositoryProvider.notifier).selectTab(tab.id);
|
||||
if (sourceSearchQuery.isNotEmpty &&
|
||||
ref.read(findInPageControllerProvider(tabId)) ==
|
||||
FindInPageState.hidden()) {
|
||||
await ref
|
||||
.read(findInPageControllerProvider(tabId).notifier)
|
||||
.findAll(text: sourceSearchQuery!);
|
||||
}
|
||||
} else {
|
||||
onClose();
|
||||
}
|
||||
|
||||
+4
-10
@@ -1,14 +1,13 @@
|
||||
import 'package:nullability/nullability.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:weblibre/core/logger.dart';
|
||||
import 'package:weblibre/features/geckoview/domain/providers/selected_tab.dart';
|
||||
import 'package:weblibre/features/geckoview/domain/providers/tab_state.dart';
|
||||
import 'package:weblibre/features/geckoview/features/find_in_page/domain/entities/find_in_page_state.dart';
|
||||
import 'package:weblibre/features/geckoview/features/find_in_page/domain/repositories/find_in_page.dart';
|
||||
|
||||
part 'find_in_page.g.dart';
|
||||
|
||||
@Riverpod()
|
||||
@Riverpod(keepAlive: true)
|
||||
class FindInPageController extends _$FindInPageController {
|
||||
void show() {
|
||||
state = state.copyWith.visible(true);
|
||||
@@ -20,7 +19,6 @@ class FindInPageController extends _$FindInPageController {
|
||||
}
|
||||
|
||||
Future<void> findAll({required String text}) {
|
||||
final tabId = ref.read(selectedTabProvider);
|
||||
final service = ref.read(findInPageRepositoryProvider(tabId).notifier);
|
||||
|
||||
state = FindInPageState(visible: true, lastSearchText: text);
|
||||
@@ -29,7 +27,6 @@ class FindInPageController extends _$FindInPageController {
|
||||
}
|
||||
|
||||
Future<void> findNext({required String fallbackText, bool forward = true}) {
|
||||
final tabId = ref.read(selectedTabProvider);
|
||||
final service = ref.read(findInPageRepositoryProvider(tabId).notifier);
|
||||
|
||||
final hasMatches =
|
||||
@@ -45,17 +42,16 @@ class FindInPageController extends _$FindInPageController {
|
||||
}
|
||||
|
||||
Future<void> clearMatches() {
|
||||
final tabId = ref.read(selectedTabProvider);
|
||||
final service = ref.read(findInPageRepositoryProvider(tabId).notifier);
|
||||
|
||||
return service.clearMatches();
|
||||
}
|
||||
|
||||
@override
|
||||
FindInPageState build() {
|
||||
FindInPageState build(String tabId) {
|
||||
ref.listen(
|
||||
fireImmediately: true,
|
||||
selectedTabStateProvider,
|
||||
tabStateProvider(tabId),
|
||||
(previous, next) async {
|
||||
//Ensure state is already initialized
|
||||
if (stateOrNull != null) {
|
||||
@@ -63,10 +59,8 @@ class FindInPageController extends _$FindInPageController {
|
||||
if (previous != null && next != null) {
|
||||
final loadingOrReloading =
|
||||
previous.isLoading == true && next.isLoading == false;
|
||||
final tabSwitchWithoutResults =
|
||||
previous.id != next.id && !next.findResultState.hasMatches;
|
||||
|
||||
if (loadingOrReloading || tabSwitchWithoutResults) {
|
||||
if (loadingOrReloading) {
|
||||
await findAll(text: state.lastSearchText!);
|
||||
}
|
||||
}
|
||||
|
||||
+149
-12
@@ -7,21 +7,158 @@ part of 'find_in_page.dart';
|
||||
// **************************************************************************
|
||||
|
||||
String _$findInPageControllerHash() =>
|
||||
r'fd335be9345b405856cf2aa68312d4d1535d8c5e';
|
||||
r'da72e38225809af5c78a372e949a80207d7ce7c9';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
_SystemHash._();
|
||||
|
||||
static int combine(int hash, int value) {
|
||||
// ignore: parameter_assignments
|
||||
hash = 0x1fffffff & (hash + value);
|
||||
// ignore: parameter_assignments
|
||||
hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
|
||||
return hash ^ (hash >> 6);
|
||||
}
|
||||
|
||||
static int finish(int hash) {
|
||||
// ignore: parameter_assignments
|
||||
hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
|
||||
// ignore: parameter_assignments
|
||||
hash = hash ^ (hash >> 11);
|
||||
return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _$FindInPageController
|
||||
extends BuildlessNotifier<FindInPageState> {
|
||||
late final String tabId;
|
||||
|
||||
FindInPageState build(String tabId);
|
||||
}
|
||||
|
||||
/// See also [FindInPageController].
|
||||
@ProviderFor(FindInPageController)
|
||||
final findInPageControllerProvider =
|
||||
AutoDisposeNotifierProvider<FindInPageController, FindInPageState>.internal(
|
||||
FindInPageController.new,
|
||||
name: r'findInPageControllerProvider',
|
||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$findInPageControllerHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
const findInPageControllerProvider = FindInPageControllerFamily();
|
||||
|
||||
/// See also [FindInPageController].
|
||||
class FindInPageControllerFamily extends Family<FindInPageState> {
|
||||
/// See also [FindInPageController].
|
||||
const FindInPageControllerFamily();
|
||||
|
||||
/// See also [FindInPageController].
|
||||
FindInPageControllerProvider call(String tabId) {
|
||||
return FindInPageControllerProvider(tabId);
|
||||
}
|
||||
|
||||
@override
|
||||
FindInPageControllerProvider getProviderOverride(
|
||||
covariant FindInPageControllerProvider provider,
|
||||
) {
|
||||
return call(provider.tabId);
|
||||
}
|
||||
|
||||
static const Iterable<ProviderOrFamily>? _dependencies = null;
|
||||
|
||||
@override
|
||||
Iterable<ProviderOrFamily>? get dependencies => _dependencies;
|
||||
|
||||
static const Iterable<ProviderOrFamily>? _allTransitiveDependencies = null;
|
||||
|
||||
@override
|
||||
Iterable<ProviderOrFamily>? get allTransitiveDependencies =>
|
||||
_allTransitiveDependencies;
|
||||
|
||||
@override
|
||||
String? get name => r'findInPageControllerProvider';
|
||||
}
|
||||
|
||||
/// See also [FindInPageController].
|
||||
class FindInPageControllerProvider
|
||||
extends NotifierProviderImpl<FindInPageController, FindInPageState> {
|
||||
/// See also [FindInPageController].
|
||||
FindInPageControllerProvider(String tabId)
|
||||
: this._internal(
|
||||
() => FindInPageController()..tabId = tabId,
|
||||
from: findInPageControllerProvider,
|
||||
name: r'findInPageControllerProvider',
|
||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$findInPageControllerHash,
|
||||
dependencies: FindInPageControllerFamily._dependencies,
|
||||
allTransitiveDependencies:
|
||||
FindInPageControllerFamily._allTransitiveDependencies,
|
||||
tabId: tabId,
|
||||
);
|
||||
|
||||
FindInPageControllerProvider._internal(
|
||||
super._createNotifier, {
|
||||
required super.name,
|
||||
required super.dependencies,
|
||||
required super.allTransitiveDependencies,
|
||||
required super.debugGetCreateSourceHash,
|
||||
required super.from,
|
||||
required this.tabId,
|
||||
}) : super.internal();
|
||||
|
||||
final String tabId;
|
||||
|
||||
@override
|
||||
FindInPageState runNotifierBuild(covariant FindInPageController notifier) {
|
||||
return notifier.build(tabId);
|
||||
}
|
||||
|
||||
@override
|
||||
Override overrideWith(FindInPageController Function() create) {
|
||||
return ProviderOverride(
|
||||
origin: this,
|
||||
override: FindInPageControllerProvider._internal(
|
||||
() => create()..tabId = tabId,
|
||||
from: from,
|
||||
name: null,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
debugGetCreateSourceHash: null,
|
||||
tabId: tabId,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
NotifierProviderElement<FindInPageController, FindInPageState>
|
||||
createElement() {
|
||||
return _FindInPageControllerProviderElement(this);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is FindInPageControllerProvider && other.tabId == tabId;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
||||
hash = _SystemHash.combine(hash, tabId.hashCode);
|
||||
|
||||
return _SystemHash.finish(hash);
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
||||
// ignore: unused_element
|
||||
mixin FindInPageControllerRef on NotifierProviderRef<FindInPageState> {
|
||||
/// The parameter `tabId` of this provider.
|
||||
String get tabId;
|
||||
}
|
||||
|
||||
class _FindInPageControllerProviderElement
|
||||
extends NotifierProviderElement<FindInPageController, FindInPageState>
|
||||
with FindInPageControllerRef {
|
||||
_FindInPageControllerProviderElement(super.provider);
|
||||
|
||||
@override
|
||||
String get tabId => (origin as FindInPageControllerProvider).tabId;
|
||||
}
|
||||
|
||||
typedef _$FindInPageController = AutoDisposeNotifier<FindInPageState>;
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
|
||||
|
||||
+11
-7
@@ -5,13 +5,14 @@ import 'package:weblibre/features/geckoview/domain/providers/tab_state.dart';
|
||||
import 'package:weblibre/features/geckoview/features/find_in_page/presentation/controllers/find_in_page.dart';
|
||||
|
||||
class FindInPageWidget extends HookConsumerWidget {
|
||||
final String tabId;
|
||||
final EdgeInsetsGeometry padding;
|
||||
|
||||
const FindInPageWidget({this.padding = EdgeInsets.zero});
|
||||
const FindInPageWidget({required this.tabId, this.padding = EdgeInsets.zero});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final findInPageState = ref.watch(findInPageControllerProvider);
|
||||
final findInPageState = ref.watch(findInPageControllerProvider(tabId));
|
||||
final searchResult = ref.watch(
|
||||
selectedTabStateProvider.select((state) => state?.findResultState),
|
||||
);
|
||||
@@ -43,11 +44,11 @@ class FindInPageWidget extends HookConsumerWidget {
|
||||
onSubmitted: (value) async {
|
||||
if (value == '') {
|
||||
await ref
|
||||
.read(findInPageControllerProvider.notifier)
|
||||
.read(findInPageControllerProvider(tabId).notifier)
|
||||
.clearMatches();
|
||||
} else {
|
||||
await ref
|
||||
.read(findInPageControllerProvider.notifier)
|
||||
.read(findInPageControllerProvider(tabId).notifier)
|
||||
.findAll(text: value);
|
||||
}
|
||||
},
|
||||
@@ -62,7 +63,7 @@ class FindInPageWidget extends HookConsumerWidget {
|
||||
icon: const Icon(Icons.arrow_upward),
|
||||
onPressed: () async {
|
||||
await ref
|
||||
.read(findInPageControllerProvider.notifier)
|
||||
.read(findInPageControllerProvider(tabId).notifier)
|
||||
.findNext(
|
||||
forward: false,
|
||||
fallbackText: textController.text,
|
||||
@@ -73,14 +74,17 @@ class FindInPageWidget extends HookConsumerWidget {
|
||||
icon: const Icon(Icons.arrow_downward),
|
||||
onPressed: () async {
|
||||
await ref
|
||||
.read(findInPageControllerProvider.notifier)
|
||||
.read(findInPageControllerProvider(tabId).notifier)
|
||||
.findNext(fallbackText: textController.text);
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.clear),
|
||||
onPressed: () async {
|
||||
await ref.read(findInPageControllerProvider.notifier).hide();
|
||||
await ref
|
||||
.read(findInPageControllerProvider(tabId).notifier)
|
||||
.hide();
|
||||
|
||||
textController.clear();
|
||||
focusNode.requestFocus();
|
||||
},
|
||||
|
||||
@@ -12,6 +12,8 @@ class TabPreview with FastEquatable {
|
||||
|
||||
final String? content;
|
||||
|
||||
final String? sourceSearchQuery;
|
||||
|
||||
TabPreview({
|
||||
required this.id,
|
||||
required this.title,
|
||||
@@ -19,6 +21,7 @@ class TabPreview with FastEquatable {
|
||||
required this.url,
|
||||
required this.highlightedUrl,
|
||||
required this.content,
|
||||
required this.sourceSearchQuery,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -29,5 +32,6 @@ class TabPreview with FastEquatable {
|
||||
url,
|
||||
highlightedUrl,
|
||||
content,
|
||||
sourceSearchQuery,
|
||||
];
|
||||
}
|
||||
|
||||
+9
@@ -9,6 +9,8 @@ import 'package:sliver_tools/sliver_tools.dart';
|
||||
import 'package:weblibre/features/geckoview/domain/controllers/bottom_sheet.dart';
|
||||
import 'package:weblibre/features/geckoview/domain/repositories/tab.dart';
|
||||
import 'package:weblibre/features/geckoview/features/browser/domain/providers.dart';
|
||||
import 'package:weblibre/features/geckoview/features/find_in_page/domain/entities/find_in_page_state.dart';
|
||||
import 'package:weblibre/features/geckoview/features/find_in_page/presentation/controllers/find_in_page.dart';
|
||||
import 'package:weblibre/features/geckoview/features/tabs/data/entities/container_filter.dart';
|
||||
import 'package:weblibre/features/geckoview/features/tabs/data/models/container_data.dart';
|
||||
import 'package:weblibre/features/geckoview/features/tabs/domain/providers/selected_container.dart';
|
||||
@@ -139,6 +141,13 @@ class TabSearch extends HookConsumerWidget {
|
||||
await ref
|
||||
.read(tabRepositoryProvider.notifier)
|
||||
.selectTab(result.id);
|
||||
if (result.sourceSearchQuery.isNotEmpty &&
|
||||
ref.read(findInPageControllerProvider(result.id)) ==
|
||||
FindInPageState.hidden()) {
|
||||
await ref
|
||||
.read(findInPageControllerProvider(result.id).notifier)
|
||||
.findAll(text: result.sourceSearchQuery!);
|
||||
}
|
||||
|
||||
if (context.mounted) {
|
||||
ref.read(bottomSheetControllerProvider.notifier).dismiss();
|
||||
|
||||
@@ -4,16 +4,28 @@ sealed class TabEntity with FastEquatable {
|
||||
String get tabId;
|
||||
}
|
||||
|
||||
class SingleTabEntity extends TabEntity {
|
||||
class DefaultTabEntity extends TabEntity {
|
||||
@override
|
||||
final String tabId;
|
||||
|
||||
SingleTabEntity({required this.tabId});
|
||||
DefaultTabEntity({required this.tabId});
|
||||
|
||||
@override
|
||||
List<Object?> get hashParameters => [tabId];
|
||||
}
|
||||
|
||||
class SearchResultTabEntity extends TabEntity {
|
||||
@override
|
||||
final String tabId;
|
||||
|
||||
final String searchQuery;
|
||||
|
||||
SearchResultTabEntity({required this.tabId, required this.searchQuery});
|
||||
|
||||
@override
|
||||
List<Object?> get hashParameters => [tabId, searchQuery];
|
||||
}
|
||||
|
||||
class TabTreeEntity extends TabEntity {
|
||||
@override
|
||||
final String tabId;
|
||||
|
||||
@@ -18,26 +18,31 @@ class TabSearchRepository extends _$TabSearchRepository {
|
||||
String ellipsis = '…',
|
||||
}) async {
|
||||
if (input.isNotEmpty) {
|
||||
state = await AsyncValue.guard(
|
||||
() => ref
|
||||
.read(tabDatabaseProvider)
|
||||
.tabDao
|
||||
.queryTabs(
|
||||
matchPrefix: matchPrefix,
|
||||
matchSuffix: matchSuffix,
|
||||
ellipsis: ellipsis,
|
||||
snippetLength: snippetLength,
|
||||
searchString: input,
|
||||
)
|
||||
.get(),
|
||||
);
|
||||
state = await AsyncValue.guard(() async {
|
||||
return (
|
||||
query: input,
|
||||
results: await ref
|
||||
.read(tabDatabaseProvider)
|
||||
.tabDao
|
||||
.queryTabs(
|
||||
matchPrefix: matchPrefix,
|
||||
matchSuffix: matchSuffix,
|
||||
ellipsis: ellipsis,
|
||||
snippetLength: snippetLength,
|
||||
searchString: input,
|
||||
)
|
||||
.get(),
|
||||
);
|
||||
});
|
||||
} else {
|
||||
state = const AsyncValue.data(null);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<TabQueryResult>?> build(TabSearchPartition partition) {
|
||||
Future<({String query, List<TabQueryResult> results})?> build(
|
||||
TabSearchPartition partition,
|
||||
) {
|
||||
return Future.value();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ part of 'tab_search.dart';
|
||||
// **************************************************************************
|
||||
|
||||
String _$tabSearchRepositoryHash() =>
|
||||
r'd442c384a5a867f4ff28465f524a6ef67521d5ae';
|
||||
r'ac2381c692b9caf93f26f302d15e0160c098917a';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
@@ -31,10 +31,15 @@ class _SystemHash {
|
||||
}
|
||||
|
||||
abstract class _$TabSearchRepository
|
||||
extends BuildlessAutoDisposeAsyncNotifier<List<TabQueryResult>?> {
|
||||
extends
|
||||
BuildlessAutoDisposeAsyncNotifier<
|
||||
({String query, List<TabQueryResult> results})?
|
||||
> {
|
||||
late final TabSearchPartition partition;
|
||||
|
||||
FutureOr<List<TabQueryResult>?> build(TabSearchPartition partition);
|
||||
FutureOr<({String query, List<TabQueryResult> results})?> build(
|
||||
TabSearchPartition partition,
|
||||
);
|
||||
}
|
||||
|
||||
/// See also [TabSearchRepository].
|
||||
@@ -43,7 +48,8 @@ const tabSearchRepositoryProvider = TabSearchRepositoryFamily();
|
||||
|
||||
/// See also [TabSearchRepository].
|
||||
class TabSearchRepositoryFamily
|
||||
extends Family<AsyncValue<List<TabQueryResult>?>> {
|
||||
extends
|
||||
Family<AsyncValue<({String query, List<TabQueryResult> results})?>> {
|
||||
/// See also [TabSearchRepository].
|
||||
const TabSearchRepositoryFamily();
|
||||
|
||||
@@ -79,7 +85,7 @@ class TabSearchRepositoryProvider
|
||||
extends
|
||||
AutoDisposeAsyncNotifierProviderImpl<
|
||||
TabSearchRepository,
|
||||
List<TabQueryResult>?
|
||||
({String query, List<TabQueryResult> results})?
|
||||
> {
|
||||
/// See also [TabSearchRepository].
|
||||
TabSearchRepositoryProvider(TabSearchPartition partition)
|
||||
@@ -109,7 +115,7 @@ class TabSearchRepositoryProvider
|
||||
final TabSearchPartition partition;
|
||||
|
||||
@override
|
||||
FutureOr<List<TabQueryResult>?> runNotifierBuild(
|
||||
FutureOr<({String query, List<TabQueryResult> results})?> runNotifierBuild(
|
||||
covariant TabSearchRepository notifier,
|
||||
) {
|
||||
return notifier.build(partition);
|
||||
@@ -134,7 +140,7 @@ class TabSearchRepositoryProvider
|
||||
@override
|
||||
AutoDisposeAsyncNotifierProviderElement<
|
||||
TabSearchRepository,
|
||||
List<TabQueryResult>?
|
||||
({String query, List<TabQueryResult> results})?
|
||||
>
|
||||
createElement() {
|
||||
return _TabSearchRepositoryProviderElement(this);
|
||||
@@ -157,7 +163,10 @@ class TabSearchRepositoryProvider
|
||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
||||
// ignore: unused_element
|
||||
mixin TabSearchRepositoryRef
|
||||
on AutoDisposeAsyncNotifierProviderRef<List<TabQueryResult>?> {
|
||||
on
|
||||
AutoDisposeAsyncNotifierProviderRef<
|
||||
({String query, List<TabQueryResult> results})?
|
||||
> {
|
||||
/// The parameter `partition` of this provider.
|
||||
TabSearchPartition get partition;
|
||||
}
|
||||
@@ -166,7 +175,7 @@ class _TabSearchRepositoryProviderElement
|
||||
extends
|
||||
AutoDisposeAsyncNotifierProviderElement<
|
||||
TabSearchRepository,
|
||||
List<TabQueryResult>?
|
||||
({String query, List<TabQueryResult> results})?
|
||||
>
|
||||
with TabSearchRepositoryRef {
|
||||
_TabSearchRepositoryProviderElement(super.provider);
|
||||
|
||||
Reference in New Issue
Block a user