automatic find in page for search results

This commit is contained in:
Fabian Freund
2025-07-02 01:41:41 +02:00
parent 25e2ffb1cd
commit 46149d1965
18 changed files with 292 additions and 70 deletions
@@ -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)
@@ -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);
},
),
),
@@ -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'),
@@ -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();
}
@@ -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!);
}
}
@@ -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
@@ -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,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);