diff --git a/lib/screens/mapflow_shell.dart b/lib/screens/mapflow_shell.dart index b3c335b..b61a7ca 100644 --- a/lib/screens/mapflow_shell.dart +++ b/lib/screens/mapflow_shell.dart @@ -726,7 +726,7 @@ class _AddExperienceFlowState extends ConsumerState { final _recorder = AudioRecorder(); final _waveSamples = List.filled(64, 0.04); - late final Future> _nearbyPlacesFuture; + Future>? _nearbyPlacesFuture; Timer? _timer; StreamSubscription? _audioStreamSub; var _step = 0; @@ -734,12 +734,10 @@ class _AddExperienceFlowState extends ConsumerState { var _recording = false; var _submitting = false; var _micAllowed = true; - PlaceRecommendation? _selectedPlace; @override void initState() { super.initState(); - _nearbyPlacesFuture = _loadNearbyPlaces(); } @override @@ -851,19 +849,8 @@ class _AddExperienceFlowState extends ConsumerState { final controller = ref.read(placeControllerProvider.notifier); final content = switch (_step) { 0 => _IntroStep(onNext: () => setState(() => _step = 1)), - 1 => _PlaceStep( - placesFuture: _nearbyPlacesFuture, - radiusMeters: _nearbyPlaceRadiusMeters, - onSelect: (place) { - setState(() { - _selectedPlace = place; - _step = 2; - }); - controller.setReviewPlace(place.name); - }, - ), - _ => _VoiceStep( - placeName: _selectedPlace?.name ?? '', + 1 => _VoiceStep( + placeName: '', hasTelegramAuth: widget.hasTelegramAuth, seconds: _seconds, minimumSeconds: _minimumVoiceSeconds, @@ -875,16 +862,23 @@ class _AddExperienceFlowState extends ConsumerState { canContinue: widget.hasTelegramAuth && _seconds >= _minimumVoiceSeconds, onToggleRecording: _toggleRecording, onNext: () async { - final selectedPlace = _selectedPlace; - if (selectedPlace == null) { - return; - } if (_recording) { await _stopRecording(); } + setState(() { + _nearbyPlacesFuture = _loadNearbyPlaces(); + _step = 2; + }); + }, + ), + _ => _PlaceStep( + placesFuture: _nearbyPlacesFuture, + radiusMeters: _nearbyPlaceRadiusMeters, + isSubmitting: _submitting, + onSelect: (place) async { setState(() => _submitting = true); - controller.setReviewPlace(selectedPlace.name); - await controller.publishReview(place: selectedPlace); + controller.setReviewPlace(place.name); + await controller.publishReview(place: place); if (!context.mounted) { return; } @@ -967,12 +961,14 @@ class _PlaceStep extends StatelessWidget { const _PlaceStep({ required this.placesFuture, required this.radiusMeters, + required this.isSubmitting, required this.onSelect, }); - final Future> placesFuture; + final Future>? placesFuture; final int radiusMeters; - final ValueChanged onSelect; + final bool isSubmitting; + final Future Function(PlaceRecommendation) onSelect; @override Widget build(BuildContext context) { @@ -1021,7 +1017,7 @@ class _PlaceStep extends StatelessWidget { itemBuilder: (context, index) { final place = places[index]; return ListTile( - onTap: () => onSelect(place), + onTap: isSubmitting ? null : () => onSelect(place), contentPadding: const EdgeInsets.symmetric( horizontal: 14, vertical: 8, @@ -1083,16 +1079,18 @@ class _VoiceStep extends StatelessWidget { return Column( children: [ - Text( - placeName.trim().isEmpty ? 'Место' : placeName.trim(), - maxLines: 1, - overflow: TextOverflow.ellipsis, - textAlign: TextAlign.center, - style: Theme.of( - context, - ).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.w900), - ), - const SizedBox(height: 10), + if (placeName.trim().isNotEmpty) ...[ + Text( + placeName.trim(), + maxLines: 1, + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.center, + style: Theme.of( + context, + ).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.w900), + ), + const SizedBox(height: 10), + ], Expanded( child: Center( child: _VoiceWave(