feat(app): add manual entry and sharing flows
This commit is contained in:
@@ -12,7 +12,10 @@ final restaurantListProvider = StreamProvider<List<Restaurant>>((ref) {
|
||||
});
|
||||
|
||||
/// 특정 맛집 Provider
|
||||
final restaurantProvider = FutureProvider.family<Restaurant?, String>((ref, id) async {
|
||||
final restaurantProvider = FutureProvider.family<Restaurant?, String>((
|
||||
ref,
|
||||
id,
|
||||
) async {
|
||||
final repository = ref.watch(restaurantRepositoryProvider);
|
||||
return repository.getRestaurantById(id);
|
||||
});
|
||||
@@ -43,7 +46,7 @@ class RestaurantNotifier extends StateNotifier<AsyncValue<void>> {
|
||||
required DataSource source,
|
||||
}) async {
|
||||
state = const AsyncValue.loading();
|
||||
|
||||
|
||||
try {
|
||||
final restaurant = Restaurant(
|
||||
id: const Uuid().v4(),
|
||||
@@ -71,7 +74,7 @@ class RestaurantNotifier extends StateNotifier<AsyncValue<void>> {
|
||||
/// 맛집 수정
|
||||
Future<void> updateRestaurant(Restaurant restaurant) async {
|
||||
state = const AsyncValue.loading();
|
||||
|
||||
|
||||
try {
|
||||
final updated = Restaurant(
|
||||
id: restaurant.id,
|
||||
@@ -100,7 +103,7 @@ class RestaurantNotifier extends StateNotifier<AsyncValue<void>> {
|
||||
/// 맛집 삭제
|
||||
Future<void> deleteRestaurant(String id) async {
|
||||
state = const AsyncValue.loading();
|
||||
|
||||
|
||||
try {
|
||||
await _repository.deleteRestaurant(id);
|
||||
state = const AsyncValue.data(null);
|
||||
@@ -110,7 +113,10 @@ class RestaurantNotifier extends StateNotifier<AsyncValue<void>> {
|
||||
}
|
||||
|
||||
/// 마지막 방문일 업데이트
|
||||
Future<void> updateLastVisitDate(String restaurantId, DateTime visitDate) async {
|
||||
Future<void> updateLastVisitDate(
|
||||
String restaurantId,
|
||||
DateTime visitDate,
|
||||
) async {
|
||||
try {
|
||||
await _repository.updateLastVisitDate(restaurantId, visitDate);
|
||||
} catch (e, stack) {
|
||||
@@ -121,7 +127,7 @@ class RestaurantNotifier extends StateNotifier<AsyncValue<void>> {
|
||||
/// 네이버 지도 URL로부터 맛집 추가
|
||||
Future<Restaurant> addRestaurantFromUrl(String url) async {
|
||||
state = const AsyncValue.loading();
|
||||
|
||||
|
||||
try {
|
||||
final restaurant = await _repository.addRestaurantFromUrl(url);
|
||||
state = const AsyncValue.data(null);
|
||||
@@ -135,7 +141,7 @@ class RestaurantNotifier extends StateNotifier<AsyncValue<void>> {
|
||||
/// 미리 생성된 Restaurant 객체를 직접 추가
|
||||
Future<void> addRestaurantDirect(Restaurant restaurant) async {
|
||||
state = const AsyncValue.loading();
|
||||
|
||||
|
||||
try {
|
||||
await _repository.addRestaurant(restaurant);
|
||||
state = const AsyncValue.data(null);
|
||||
@@ -147,38 +153,46 @@ class RestaurantNotifier extends StateNotifier<AsyncValue<void>> {
|
||||
}
|
||||
|
||||
/// RestaurantNotifier Provider
|
||||
final restaurantNotifierProvider = StateNotifierProvider<RestaurantNotifier, AsyncValue<void>>((ref) {
|
||||
final repository = ref.watch(restaurantRepositoryProvider);
|
||||
return RestaurantNotifier(repository);
|
||||
});
|
||||
final restaurantNotifierProvider =
|
||||
StateNotifierProvider<RestaurantNotifier, AsyncValue<void>>((ref) {
|
||||
final repository = ref.watch(restaurantRepositoryProvider);
|
||||
return RestaurantNotifier(repository);
|
||||
});
|
||||
|
||||
/// 거리 내 맛집 Provider
|
||||
final restaurantsWithinDistanceProvider = FutureProvider.family<List<Restaurant>, ({double latitude, double longitude, double maxDistance})>((ref, params) async {
|
||||
final repository = ref.watch(restaurantRepositoryProvider);
|
||||
return repository.getRestaurantsWithinDistance(
|
||||
userLatitude: params.latitude,
|
||||
userLongitude: params.longitude,
|
||||
maxDistanceInMeters: params.maxDistance,
|
||||
);
|
||||
});
|
||||
final restaurantsWithinDistanceProvider =
|
||||
FutureProvider.family<
|
||||
List<Restaurant>,
|
||||
({double latitude, double longitude, double maxDistance})
|
||||
>((ref, params) async {
|
||||
final repository = ref.watch(restaurantRepositoryProvider);
|
||||
return repository.getRestaurantsWithinDistance(
|
||||
userLatitude: params.latitude,
|
||||
userLongitude: params.longitude,
|
||||
maxDistanceInMeters: params.maxDistance,
|
||||
);
|
||||
});
|
||||
|
||||
/// n일 이내 방문하지 않은 맛집 Provider
|
||||
final restaurantsNotVisitedInDaysProvider = FutureProvider.family<List<Restaurant>, int>((ref, days) async {
|
||||
final repository = ref.watch(restaurantRepositoryProvider);
|
||||
return repository.getRestaurantsNotVisitedInDays(days);
|
||||
});
|
||||
final restaurantsNotVisitedInDaysProvider =
|
||||
FutureProvider.family<List<Restaurant>, int>((ref, days) async {
|
||||
final repository = ref.watch(restaurantRepositoryProvider);
|
||||
return repository.getRestaurantsNotVisitedInDays(days);
|
||||
});
|
||||
|
||||
/// 검색어로 맛집 검색 Provider
|
||||
final searchRestaurantsProvider = FutureProvider.family<List<Restaurant>, String>((ref, query) async {
|
||||
final repository = ref.watch(restaurantRepositoryProvider);
|
||||
return repository.searchRestaurants(query);
|
||||
});
|
||||
final searchRestaurantsProvider =
|
||||
FutureProvider.family<List<Restaurant>, String>((ref, query) async {
|
||||
final repository = ref.watch(restaurantRepositoryProvider);
|
||||
return repository.searchRestaurants(query);
|
||||
});
|
||||
|
||||
/// 카테고리별 맛집 Provider
|
||||
final restaurantsByCategoryProvider = FutureProvider.family<List<Restaurant>, String>((ref, category) async {
|
||||
final repository = ref.watch(restaurantRepositoryProvider);
|
||||
return repository.getRestaurantsByCategory(category);
|
||||
});
|
||||
final restaurantsByCategoryProvider =
|
||||
FutureProvider.family<List<Restaurant>, String>((ref, category) async {
|
||||
final repository = ref.watch(restaurantRepositoryProvider);
|
||||
return repository.getRestaurantsByCategory(category);
|
||||
});
|
||||
|
||||
/// 검색 쿼리 상태 Provider
|
||||
final searchQueryProvider = StateProvider<String>((ref) => '');
|
||||
@@ -187,37 +201,45 @@ final searchQueryProvider = StateProvider<String>((ref) => '');
|
||||
final selectedCategoryProvider = StateProvider<String?>((ref) => null);
|
||||
|
||||
/// 필터링된 맛집 목록 Provider (검색 + 카테고리)
|
||||
final filteredRestaurantsProvider = StreamProvider<List<Restaurant>>((ref) async* {
|
||||
final filteredRestaurantsProvider = StreamProvider<List<Restaurant>>((
|
||||
ref,
|
||||
) async* {
|
||||
final searchQuery = ref.watch(searchQueryProvider);
|
||||
final selectedCategory = ref.watch(selectedCategoryProvider);
|
||||
final restaurantsStream = ref.watch(restaurantListProvider.stream);
|
||||
|
||||
|
||||
await for (final restaurants in restaurantsStream) {
|
||||
var filtered = restaurants;
|
||||
|
||||
|
||||
// 검색 필터 적용
|
||||
if (searchQuery.isNotEmpty) {
|
||||
final lowercaseQuery = searchQuery.toLowerCase();
|
||||
filtered = filtered.where((restaurant) {
|
||||
return restaurant.name.toLowerCase().contains(lowercaseQuery) ||
|
||||
(restaurant.description?.toLowerCase().contains(lowercaseQuery) ?? false) ||
|
||||
(restaurant.description?.toLowerCase().contains(lowercaseQuery) ??
|
||||
false) ||
|
||||
restaurant.category.toLowerCase().contains(lowercaseQuery);
|
||||
}).toList();
|
||||
}
|
||||
|
||||
|
||||
// 카테고리 필터 적용
|
||||
if (selectedCategory != null) {
|
||||
filtered = filtered.where((restaurant) {
|
||||
// 정확한 일치 또는 부분 일치 확인
|
||||
// restaurant.category가 "음식점>한식>백반/한정식" 형태일 때
|
||||
// selectedCategory가 "백반/한정식"이면 매칭
|
||||
return restaurant.category == selectedCategory ||
|
||||
restaurant.category.contains(selectedCategory) ||
|
||||
CategoryMapper.normalizeNaverCategory(restaurant.category, restaurant.subCategory) == selectedCategory ||
|
||||
CategoryMapper.getDisplayName(restaurant.category) == selectedCategory;
|
||||
return restaurant.category == selectedCategory ||
|
||||
restaurant.category.contains(selectedCategory) ||
|
||||
CategoryMapper.normalizeNaverCategory(
|
||||
restaurant.category,
|
||||
restaurant.subCategory,
|
||||
) ==
|
||||
selectedCategory ||
|
||||
CategoryMapper.getDisplayName(restaurant.category) ==
|
||||
selectedCategory;
|
||||
}).toList();
|
||||
}
|
||||
|
||||
|
||||
yield filtered;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user