fix search start for weblibre search bang

This commit is contained in:
Fabian Freund
2026-05-24 10:30:50 +02:00
parent 0b0ef38636
commit 46a3b250c2
7 changed files with 65 additions and 2 deletions
@@ -91,6 +91,8 @@ class SearchRoute extends GoRouteData with $SearchRoute {
final bool launchedFromIntent; final bool launchedFromIntent;
final bool autoSubmitSearch;
/// When provided, the search screen will load URLs into this existing tab /// When provided, the search screen will load URLs into this existing tab
/// instead of creating a new tab. This also changes the UI to show /// instead of creating a new tab. This also changes the UI to show
/// site-specific bangs instead of the tab type selector. /// site-specific bangs instead of the tab type selector.
@@ -100,6 +102,7 @@ class SearchRoute extends GoRouteData with $SearchRoute {
required this.tabType, required this.tabType,
this.searchText = SearchRoute.emptySearchText, this.searchText = SearchRoute.emptySearchText,
this.launchedFromIntent = false, this.launchedFromIntent = false,
this.autoSubmitSearch = false,
this.tabId, this.tabId,
}); });
@@ -111,6 +114,7 @@ class SearchRoute extends GoRouteData with $SearchRoute {
? null ? null
: searchText, : searchText,
launchedFromIntent: launchedFromIntent, launchedFromIntent: launchedFromIntent,
autoSubmitSearch: autoSubmitSearch,
tabId: tabId, tabId: tabId,
); );
} }
@@ -632,6 +632,13 @@ mixin $SearchRoute on GoRouteData {
_$boolConverter, _$boolConverter,
) ?? ) ??
false, false,
autoSubmitSearch:
_$convertMapValue(
'auto-submit-search',
state.uri.queryParameters,
_$boolConverter,
) ??
false,
tabId: state.uri.queryParameters['tab-id'], tabId: state.uri.queryParameters['tab-id'],
); );
@@ -643,6 +650,8 @@ mixin $SearchRoute on GoRouteData {
queryParams: { queryParams: {
if (_self.launchedFromIntent != false) if (_self.launchedFromIntent != false)
'launched-from-intent': _self.launchedFromIntent.toString(), 'launched-from-intent': _self.launchedFromIntent.toString(),
if (_self.autoSubmitSearch != false)
'auto-submit-search': _self.autoSubmitSearch.toString(),
if (_self.tabId != null) 'tab-id': _self.tabId, if (_self.tabId != null) 'tab-id': _self.tabId,
}, },
); );
@@ -21,4 +21,4 @@ const webSearchBangKey = BangKey(
); );
bool isWebSearchBang(BangData? bang) => bool isWebSearchBang(BangData? bang) =>
bang != null && bang.group == BangGroup.weblibre; bang != null && bang.toKey() == webSearchBangKey;
@@ -26,6 +26,7 @@ import 'package:url_launcher/url_launcher.dart';
import 'package:weblibre/core/logger.dart'; import 'package:weblibre/core/logger.dart';
import 'package:weblibre/core/providers/router.dart'; import 'package:weblibre/core/providers/router.dart';
import 'package:weblibre/core/routing/routes.dart'; import 'package:weblibre/core/routing/routes.dart';
import 'package:weblibre/features/bangs/data/models/web_search_bang.dart';
import 'package:weblibre/features/bangs/domain/providers/bangs.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/selected_tab.dart';
import 'package:weblibre/features/geckoview/domain/providers/tab_state.dart'; import 'package:weblibre/features/geckoview/domain/providers/tab_state.dart';
@@ -83,6 +84,20 @@ GeckoSelectionActionService selectionActionService(Ref ref) {
.effectiveDefaultCreateTabType, .effectiveDefaultCreateTabType,
); );
if (isWebSearchBang(searchBang)) {
final router = await ref.read(routerProvider.future);
if (!ref.mounted) return;
await router.push(
SearchRoute(
tabType: tabMode.toTabType(),
searchText: text,
autoSubmitSearch: true,
).location,
);
return;
}
await ref await ref
.read(tabRepositoryProvider.notifier) .read(tabRepositoryProvider.notifier)
.addTab( .addTab(
@@ -55,7 +55,7 @@ final class SelectionActionServiceProvider
} }
String _$selectionActionServiceHash() => String _$selectionActionServiceHash() =>
r'78593799e8d903de415cf49ebb3acfb73e45d878'; r'c2cdd69d3dc4c2fe4bb54658d76ca26efb5bfc74';
@ProviderFor(eventService) @ProviderFor(eventService)
final eventServiceProvider = EventServiceProvider._(); final eventServiceProvider = EventServiceProvider._();
@@ -30,6 +30,7 @@ import 'package:weblibre/core/logger.dart';
import 'package:weblibre/core/providers/device_info.dart'; import 'package:weblibre/core/providers/device_info.dart';
import 'package:weblibre/core/providers/router.dart'; import 'package:weblibre/core/providers/router.dart';
import 'package:weblibre/core/routing/routes.dart'; import 'package:weblibre/core/routing/routes.dart';
import 'package:weblibre/features/bangs/data/models/web_search_bang.dart';
import 'package:weblibre/features/bangs/domain/providers/bangs.dart'; import 'package:weblibre/features/bangs/domain/providers/bangs.dart';
import 'package:weblibre/features/bangs/domain/services/search_history_cleanup.dart'; import 'package:weblibre/features/bangs/domain/services/search_history_cleanup.dart';
import 'package:weblibre/features/geckoview/domain/entities/tab_container_selection.dart'; import 'package:weblibre/features/geckoview/domain/entities/tab_container_selection.dart';
@@ -436,6 +437,19 @@ class _BrowserViewState extends ConsumerState<BrowserView>
ref.read(selectedBangDataProvider()) ?? ref.read(selectedBangDataProvider()) ??
await ref.read(defaultSearchBangProvider.future); await ref.read(defaultSearchBangProvider.future);
if (bang != null && isWebSearchBang(bang)) {
final router = await ref.read(routerProvider.future);
await router.push(
SearchRoute(
tabType: tabMode.toTabType(),
searchText: sharedContent.text,
launchedFromIntent: true,
autoSubmitSearch: true,
).location,
);
break;
}
await ref await ref
.read(tabRepositoryProvider.notifier) .read(tabRepositoryProvider.notifier)
.addTab( .addTab(
@@ -83,6 +83,7 @@ class SearchScreen extends HookConsumerWidget {
final String? initialSearchText; final String? initialSearchText;
final TabType tabType; final TabType tabType;
final bool launchedFromIntent; final bool launchedFromIntent;
final bool autoSubmitSearch;
/// When provided, URLs will be loaded into this existing tab. /// When provided, URLs will be loaded into this existing tab.
/// When null, a new tab will be created. /// When null, a new tab will be created.
@@ -93,6 +94,7 @@ class SearchScreen extends HookConsumerWidget {
required this.initialSearchText, required this.initialSearchText,
required this.tabType, required this.tabType,
this.launchedFromIntent = false, this.launchedFromIntent = false,
this.autoSubmitSearch = false,
this.tabId, this.tabId,
}); });
@@ -430,6 +432,25 @@ class SearchScreen extends HookConsumerWidget {
} }
} }
final autoSubmittedInitialSearch = useRef(false);
useEffect(() {
if (!autoSubmitSearch ||
autoSubmittedInitialSearch.value ||
initialSearchText == null ||
initialSearchText!.trim().isEmpty ||
activeBang == null ||
!isWebSearchBang(activeBang)) {
return null;
}
autoSubmittedInitialSearch.value = true;
WidgetsBinding.instance.addPostFrameCallback((_) {
unawaited(resolveSearchUri(activeBang, initialSearchText!));
});
return null;
}, [autoSubmitSearch, initialSearchText, activeBang]);
// Persist the results scroll offset across navigation so returning to // Persist the results scroll offset across navigation so returning to
// the search screen after opening a result restores the user's place // the search screen after opening a result restores the user's place
// instead of jumping back to the top. The offset provider is reset on // instead of jumping back to the top. The offset provider is reset on