feat(app): stabilize recommendation flow
This commit is contained in:
@@ -3,6 +3,7 @@ import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunchpick/core/constants/app_colors.dart';
|
||||
import 'package:lunchpick/core/constants/app_typography.dart';
|
||||
import 'package:lunchpick/core/utils/distance_calculator.dart';
|
||||
import 'package:lunchpick/domain/entities/restaurant.dart';
|
||||
|
||||
enum RecommendationDialogResult { confirm, reroll, autoConfirm }
|
||||
@@ -10,11 +11,15 @@ enum RecommendationDialogResult { confirm, reroll, autoConfirm }
|
||||
class RecommendationResultDialog extends StatefulWidget {
|
||||
final Restaurant restaurant;
|
||||
final Duration autoConfirmDuration;
|
||||
final double? currentLatitude;
|
||||
final double? currentLongitude;
|
||||
|
||||
const RecommendationResultDialog({
|
||||
super.key,
|
||||
required this.restaurant,
|
||||
this.autoConfirmDuration = const Duration(seconds: 12),
|
||||
this.currentLatitude,
|
||||
this.currentLongitude,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -26,10 +31,12 @@ class _RecommendationResultDialogState
|
||||
extends State<RecommendationResultDialog> {
|
||||
Timer? _autoConfirmTimer;
|
||||
bool _didComplete = false;
|
||||
double? _distanceKm;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_calculateDistance();
|
||||
_startAutoConfirmTimer();
|
||||
}
|
||||
|
||||
@@ -47,6 +54,27 @@ class _RecommendationResultDialogState
|
||||
});
|
||||
}
|
||||
|
||||
void _calculateDistance() {
|
||||
final lat = widget.currentLatitude;
|
||||
final lon = widget.currentLongitude;
|
||||
if (lat == null || lon == null) return;
|
||||
|
||||
_distanceKm = DistanceCalculator.calculateDistance(
|
||||
lat1: lat,
|
||||
lon1: lon,
|
||||
lat2: widget.restaurant.latitude,
|
||||
lon2: widget.restaurant.longitude,
|
||||
);
|
||||
}
|
||||
|
||||
String _formatDistance(double distanceKm) {
|
||||
final meters = distanceKm * 1000;
|
||||
if (meters >= 1000) {
|
||||
return '${distanceKm.toStringAsFixed(1)} km';
|
||||
}
|
||||
return '${meters.round()} m';
|
||||
}
|
||||
|
||||
Future<void> _handleResult(RecommendationDialogResult result) async {
|
||||
if (_didComplete) return;
|
||||
_didComplete = true;
|
||||
@@ -177,6 +205,26 @@ class _RecommendationResultDialogState
|
||||
),
|
||||
],
|
||||
),
|
||||
if (_distanceKm != null) ...[
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.place,
|
||||
size: 20,
|
||||
color: AppColors.lightPrimary,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
_formatDistance(_distanceKm!),
|
||||
style: AppTypography.body2(isDark).copyWith(
|
||||
color: AppColors.lightPrimary,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
if (widget.restaurant.phoneNumber != null) ...[
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
@@ -237,14 +285,14 @@ class _RecommendationResultDialogState
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
child: const Text('닫기'),
|
||||
child: const Text('오늘의 선택!'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'조용히 두면 자동으로 방문 처리되고 알림이 예약됩니다.',
|
||||
'앱을 종료하면 자동으로 선택이 확정됩니다.',
|
||||
style: AppTypography.caption(isDark),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user