feat(app): seed restaurants, geocode addresses, refresh sharing
This commit is contained in:
@@ -217,28 +217,31 @@ class _RandomSelectionScreenState extends ConsumerState<RandomSelectionScreen> {
|
||||
Consumer(
|
||||
builder: (context, ref, child) {
|
||||
final locationAsync = ref.watch(
|
||||
currentLocationProvider,
|
||||
currentLocationWithFallbackProvider,
|
||||
);
|
||||
final restaurantsAsync = ref.watch(
|
||||
restaurantListProvider,
|
||||
);
|
||||
|
||||
if (locationAsync.hasValue &&
|
||||
restaurantsAsync.hasValue) {
|
||||
final location = locationAsync.value;
|
||||
final restaurants = restaurantsAsync.value;
|
||||
final location = locationAsync.maybeWhen(
|
||||
data: (pos) => pos,
|
||||
orElse: () => null,
|
||||
);
|
||||
final restaurants = restaurantsAsync.maybeWhen(
|
||||
data: (list) => list,
|
||||
orElse: () => null,
|
||||
);
|
||||
|
||||
if (location != null && restaurants != null) {
|
||||
final count = _getRestaurantCountInRange(
|
||||
restaurants,
|
||||
location,
|
||||
_distanceValue,
|
||||
);
|
||||
return Text(
|
||||
'$count개 맛집 포함',
|
||||
style: AppTypography.caption(isDark),
|
||||
);
|
||||
}
|
||||
if (location != null && restaurants != null) {
|
||||
final count = _getRestaurantCountInRange(
|
||||
restaurants,
|
||||
location,
|
||||
_distanceValue,
|
||||
);
|
||||
return Text(
|
||||
'$count개 맛집 포함',
|
||||
style: AppTypography.caption(isDark),
|
||||
);
|
||||
}
|
||||
|
||||
return Text(
|
||||
@@ -439,15 +442,17 @@ class _RandomSelectionScreenState extends ConsumerState<RandomSelectionScreen> {
|
||||
}
|
||||
|
||||
bool _canRecommend() {
|
||||
final locationAsync = ref.read(currentLocationProvider);
|
||||
final locationAsync = ref.read(currentLocationWithFallbackProvider);
|
||||
final restaurantsAsync = ref.read(restaurantListProvider);
|
||||
|
||||
if (!locationAsync.hasValue || !restaurantsAsync.hasValue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final location = locationAsync.value;
|
||||
final restaurants = restaurantsAsync.value;
|
||||
final location = locationAsync.maybeWhen(
|
||||
data: (pos) => pos,
|
||||
orElse: () => null,
|
||||
);
|
||||
final restaurants = restaurantsAsync.maybeWhen(
|
||||
data: (list) => list,
|
||||
orElse: () => null,
|
||||
);
|
||||
|
||||
if (location == null || restaurants == null || restaurants.isEmpty) {
|
||||
return false;
|
||||
@@ -491,10 +496,7 @@ class _RandomSelectionScreenState extends ConsumerState<RandomSelectionScreen> {
|
||||
final adWatched = await adService.showInterstitialAd(context);
|
||||
if (!mounted) return;
|
||||
if (!adWatched) {
|
||||
_showSnack(
|
||||
'광고를 끝까지 시청해야 추천을 받을 수 있어요.',
|
||||
backgroundColor: AppColors.lightError,
|
||||
);
|
||||
_showSnack('광고를 끝까지 시청해야 추천을 받을 수 있어요.', type: _SnackType.error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -502,10 +504,7 @@ class _RandomSelectionScreenState extends ConsumerState<RandomSelectionScreen> {
|
||||
if (!mounted) return;
|
||||
await _showRecommendationDialog(candidate, recommendedAt: recommendedAt);
|
||||
} catch (_) {
|
||||
_showSnack(
|
||||
'추천을 준비하는 중 문제가 발생했습니다.',
|
||||
backgroundColor: AppColors.lightError,
|
||||
);
|
||||
_showSnack('추천을 준비하는 중 문제가 발생했습니다.', type: _SnackType.error);
|
||||
} finally {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
@@ -531,17 +530,14 @@ class _RandomSelectionScreenState extends ConsumerState<RandomSelectionScreen> {
|
||||
|
||||
if (result.hasError) {
|
||||
final message = result.error?.toString() ?? '알 수 없는 오류';
|
||||
_showSnack(
|
||||
'추천 중 오류가 발생했습니다: $message',
|
||||
backgroundColor: AppColors.lightError,
|
||||
);
|
||||
_showSnack('추천 중 오류가 발생했습니다: $message', type: _SnackType.error);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (recommendation == null) {
|
||||
_showSnack(
|
||||
'조건에 맞는 식당이 존재하지 않습니다. 광고는 재생되지 않았습니다.',
|
||||
backgroundColor: AppColors.lightError,
|
||||
type: _SnackType.warning,
|
||||
);
|
||||
}
|
||||
return recommendation;
|
||||
@@ -626,10 +622,10 @@ class _RandomSelectionScreenState extends ConsumerState<RandomSelectionScreen> {
|
||||
if (notificationEnabled && !notificationScheduled && !kIsWeb) {
|
||||
_showSnack(
|
||||
'방문 기록은 저장됐지만 알림 권한이나 설정을 확인해 주세요. 방문 알림을 예약하지 못했습니다.',
|
||||
backgroundColor: AppColors.lightError,
|
||||
type: _SnackType.warning,
|
||||
);
|
||||
} else {
|
||||
_showSnack('맛있게 드세요! 🍴');
|
||||
_showSnack('맛있게 드세요! 🍴', type: _SnackType.success);
|
||||
}
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
@@ -637,25 +633,25 @@ class _RandomSelectionScreenState extends ConsumerState<RandomSelectionScreen> {
|
||||
});
|
||||
}
|
||||
} catch (_) {
|
||||
_showSnack(
|
||||
'방문 기록 또는 알림 예약에 실패했습니다.',
|
||||
backgroundColor: AppColors.lightError,
|
||||
);
|
||||
_showSnack('방문 기록 또는 알림 예약에 실패했습니다.', type: _SnackType.error);
|
||||
}
|
||||
}
|
||||
|
||||
void _showSnack(
|
||||
String message, {
|
||||
Color backgroundColor = AppColors.lightPrimary,
|
||||
}) {
|
||||
void _showSnack(String message, {_SnackType type = _SnackType.info}) {
|
||||
if (!mounted) return;
|
||||
final bgColor = switch (type) {
|
||||
_SnackType.success => Colors.teal.shade600,
|
||||
_SnackType.warning => Colors.orange.shade600,
|
||||
_SnackType.error => AppColors.lightError,
|
||||
_SnackType.info => Colors.blueGrey.shade600,
|
||||
};
|
||||
final topInset = MediaQuery.of(context).viewPadding.top;
|
||||
ScaffoldMessenger.of(context)
|
||||
..hideCurrentSnackBar()
|
||||
..showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(message),
|
||||
backgroundColor: backgroundColor,
|
||||
backgroundColor: bgColor,
|
||||
behavior: SnackBarBehavior.floating,
|
||||
margin: EdgeInsets.fromLTRB(
|
||||
16,
|
||||
@@ -668,3 +664,5 @@ class _RandomSelectionScreenState extends ConsumerState<RandomSelectionScreen> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
enum _SnackType { info, warning, error, success }
|
||||
|
||||
Reference in New Issue
Block a user