Backend: - GET /dishes/search — hybrid FTS (english + simple) + trgm + ILIKE search - GET /diary/recent — recently used dishes and products for the current user - product search upgraded: FTS on canonical_name and product_aliases, ranked by GREATEST(ts_rank, similarity) - importoff: collect product_name_ru/de/fr/... as product_aliases for multilingual search (e.g. "сникерс" → "Snickers") - migrations: FTS + trgm indexes merged into 001_initial_schema.sql (002 removed) Flutter: - FoodSearchSheet: debounced search field, recently-used section, product/dish results, scan-photo and barcode chips - DishPortionSheet: quick ½/1/1½/2 buttons + custom input - + button in meal card now opens FoodSearchSheet instead of going directly to AI scan - 7 new l10n keys across all 12 languages Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
28 lines
1003 B
Dart
28 lines
1003 B
Dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
|
|
import '../../core/auth/auth_provider.dart';
|
|
import '../../shared/models/product.dart';
|
|
import 'food_search_service.dart';
|
|
|
|
final foodSearchServiceProvider = Provider<FoodSearchService>(
|
|
(ref) => FoodSearchService(ref.read(apiClientProvider)),
|
|
);
|
|
|
|
/// Recently used diary items (dishes + products).
|
|
final recentDiaryItemsProvider =
|
|
FutureProvider.autoDispose<List<RecentDiaryItem>>((ref) {
|
|
return ref.read(foodSearchServiceProvider).getRecent(limit: 15);
|
|
});
|
|
|
|
/// Product search results for the given query string.
|
|
final productSearchProvider = FutureProvider.autoDispose
|
|
.family<List<CatalogProduct>, String>((ref, query) {
|
|
return ref.read(foodSearchServiceProvider).searchProducts(query);
|
|
});
|
|
|
|
/// Dish search results for the given query string.
|
|
final dishSearchProvider = FutureProvider.autoDispose
|
|
.family<List<DishSearchResult>, String>((ref, query) {
|
|
return ref.read(foodSearchServiceProvider).searchDishes(query);
|
|
});
|