generated from ttipo/project-base
fix(flutter): 대구 밖 현재 위치는 대구 도심으로 대신하고 안내함
현재 위치를 그대로 쓰면 대구 밖(서울 등)에서는 모든 칸이 "근처에 아직 없어요"로 비었다(2026-11-04 회귀 점검). 서비스 지역(대구, 군위 포함 — 백엔드 geo.ts 와 같은 영역) 밖이면 대구 도심을 기준으로 쓰고, 홈에서 "아직 대구 지역만 볼 수 있어요"를 한 번 알린다. 위치를 받지 못해 대신하는 경우도 지금까지는 기준만 조용히 바뀌었는데, 같은 방식으로 알린다. 대신한 이유는 BasePoint.fallback 에 남는다. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit was merged in pull request #7.
This commit is contained in:
@@ -44,6 +44,20 @@ class HomePage extends ConsumerWidget {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final l10n = context.l10n;
|
||||
final textTheme = Theme.of(context).textTheme;
|
||||
// 현재 위치 대신 대구 도심을 쓰게 되면 이유를 한 번 알린다(같은 이유로 다시 받을 때는 띄우지 않는다)
|
||||
ref.listen(basePointProvider.select((base) => base.value?.fallback), (
|
||||
previous,
|
||||
next,
|
||||
) {
|
||||
if (next == null || next == previous) return;
|
||||
final message = switch (next) {
|
||||
BaseFallback.unavailable => l10n.locationUnavailable,
|
||||
BaseFallback.outsideServiceArea => l10n.locationOutsideServiceArea,
|
||||
};
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text(message)));
|
||||
});
|
||||
return Scaffold(
|
||||
body: SafeArea(
|
||||
bottom: false,
|
||||
|
||||
@@ -55,17 +55,37 @@ class BaseLocationChoice {
|
||||
int get hashCode => neighborhood.hashCode;
|
||||
}
|
||||
|
||||
/// 서비스 지역(1차 출시: 대구) 대략 영역 — 2023년 편입한 군위군 포함.
|
||||
/// 백엔드 `shared/utils/geo.ts` 의 시·도 영역(27 대구)과 같은 값이다.
|
||||
const ({double latMin, double latMax, double lngMin, double lngMax})
|
||||
kServiceArea = (latMin: 35.55, latMax: 36.36, lngMin: 128.3, lngMax: 128.9);
|
||||
|
||||
/// 좌표가 서비스 지역 안인지 본다. 밖에서는 볼 장소·행사가 거의 없다
|
||||
bool isInServiceArea(GeoPoint p) =>
|
||||
p.lat >= kServiceArea.latMin &&
|
||||
p.lat <= kServiceArea.latMax &&
|
||||
p.lng >= kServiceArea.lngMin &&
|
||||
p.lng <= kServiceArea.lngMax;
|
||||
|
||||
/// 현재 위치 대신 [kFallbackNeighborhood] 를 쓴 이유
|
||||
enum BaseFallback {
|
||||
/// 위치를 받지 못했다(권한 없음·위치 서비스 꺼짐·시간 초과)
|
||||
unavailable,
|
||||
|
||||
/// 서비스 지역(대구) 밖이다 — 그대로 쓰면 모든 칸이 "근처에 아직 없어요"로 빈다
|
||||
outsideServiceArea,
|
||||
}
|
||||
|
||||
/// 실제로 조회에 쓰는 기준 좌표
|
||||
class BasePoint {
|
||||
const BasePoint({
|
||||
required this.point,
|
||||
required this.choice,
|
||||
this.fellBack = false,
|
||||
});
|
||||
const BasePoint({required this.point, required this.choice, this.fallback});
|
||||
|
||||
final GeoPoint point;
|
||||
final BaseLocationChoice choice;
|
||||
|
||||
/// 현재 위치를 고르고도 위치를 못 받아 [kFallbackNeighborhood] 를 쓴 경우
|
||||
final bool fellBack;
|
||||
/// 현재 위치를 고르고도 [kFallbackNeighborhood] 를 쓴 이유. 대신하지 않았으면 null
|
||||
final BaseFallback? fallback;
|
||||
|
||||
/// 현재 위치를 고르고도 [kFallbackNeighborhood] 를 쓴 경우
|
||||
bool get fellBack => fallback != null;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,8 @@ class BaseLocationNotifier extends Notifier<BaseLocationChoice> {
|
||||
}
|
||||
}
|
||||
|
||||
/// 조회에 쓰는 기준 좌표 — 현재 위치를 골랐는데 받지 못하면 [kFallbackNeighborhood] 로 대신한다
|
||||
/// 조회에 쓰는 기준 좌표 — 현재 위치를 골랐는데 받지 못하거나 서비스 지역(대구) 밖이면
|
||||
/// [kFallbackNeighborhood] 로 대신하고 이유를 남긴다(홈이 안내한다)
|
||||
final basePointProvider = FutureProvider<BasePoint>((ref) async {
|
||||
final choice = ref.watch(baseLocationProvider);
|
||||
final neighborhood = choice.neighborhood;
|
||||
@@ -36,10 +37,15 @@ final basePointProvider = FutureProvider<BasePoint>((ref) async {
|
||||
return BasePoint(point: neighborhood.point, choice: choice);
|
||||
}
|
||||
final current = await ref.watch(locationServiceProvider).currentPoint();
|
||||
if (current != null) return BasePoint(point: current, choice: choice);
|
||||
final BaseFallback? fallback = current == null
|
||||
? BaseFallback.unavailable
|
||||
: (isInServiceArea(current) ? null : BaseFallback.outsideServiceArea);
|
||||
if (current != null && fallback == null) {
|
||||
return BasePoint(point: current, choice: choice);
|
||||
}
|
||||
return BasePoint(
|
||||
point: kFallbackNeighborhood.point,
|
||||
choice: choice,
|
||||
fellBack: true,
|
||||
fallback: fallback,
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user