bug fixes
This commit is contained in:
@@ -10,6 +10,6 @@ class AppSettingsService {
|
||||
}
|
||||
|
||||
bool getMapSettingsFlag(String key) {
|
||||
return sharedPreferences.getBool(key) ?? false;
|
||||
return sharedPreferences.getBool(key) ?? true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@ class MapSettings {
|
||||
final bool restricted_driving_zones;
|
||||
|
||||
MapSettings({
|
||||
required this.all_placemarks,
|
||||
required this.all_zones,
|
||||
required this.parking_zones,
|
||||
required this.restricted_parking_zones,
|
||||
required this.restricted_driving_zones,
|
||||
this.all_placemarks = true,
|
||||
this.all_zones = true,
|
||||
this.parking_zones = true,
|
||||
this.restricted_parking_zones = true,
|
||||
this.restricted_driving_zones = true,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -73,7 +73,6 @@ class MapSettingsSheet extends StatelessWidget {
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
context.read<MapSettingsModalBloc>().add(ApllyButtonClick());
|
||||
context.read<MapBloc>().add(UpdateMap());
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: const Text(
|
||||
|
||||
@@ -3,8 +3,10 @@ import 'dart:ui';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import '../../../di/service_locator.dart';
|
||||
import '../../event/map_event.dart';
|
||||
import '../../event/reserved_ride_event.dart';
|
||||
import '../../state/reserved_ride_state.dart';
|
||||
import '../../viewmodel/map_bloc.dart';
|
||||
import '../../viewmodel/reserved_ride_bloc.dart';
|
||||
import '../dialog/cancel_booking_dialog.dart';
|
||||
import '../gradient_button.dart';
|
||||
@@ -125,7 +127,6 @@ class _ReservedRideSheetState extends State<ReservedRideSheet> {
|
||||
|
||||
const SizedBox(height: 20),
|
||||
|
||||
// ТАЙМЕР + ИНФО О САМОКАТЕ (КОМПАКТНЫЙ)
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
child: Row(
|
||||
@@ -227,6 +228,7 @@ class _ReservedRideSheetState extends State<ReservedRideSheet> {
|
||||
listener: (context, state) {
|
||||
if (state.rideStarted) {
|
||||
Navigator.pop(context);
|
||||
context.read<MapBloc>().add(FetchActiveOrders());
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
|
||||
@@ -15,9 +15,11 @@ import '../../../domain/usecase/add_payment_card_usecase.dart';
|
||||
import '../../../domain/usecase/get_payment_cards_usecase.dart';
|
||||
import '../../../domain/usecase/get_profile_usecase.dart';
|
||||
import '../../../domain/usecase/set_main_payment_card_usecase.dart';
|
||||
import '../../event/map_event.dart';
|
||||
import '../../event/payment_method_sheet_event.dart';
|
||||
import '../../event/tariff_sheet_event.dart';
|
||||
import '../../state/tariff_sheet_state.dart';
|
||||
import '../../viewmodel/map_bloc.dart';
|
||||
import '../../viewmodel/tariff_sheet_bloc.dart';
|
||||
import '../gradient_button.dart';
|
||||
import '../scooter/mini_battery_indicator.dart';
|
||||
@@ -62,6 +64,14 @@ class _TariffSheetState extends State<TariffSheet> {
|
||||
}
|
||||
return BlocConsumer<TariffSheetBloc, TariffSheetState>(
|
||||
listener: (context, state) {
|
||||
if (state.status == TariffSheetStatus.success &&
|
||||
state.tariffs.isNotEmpty &&
|
||||
_selectedTariffIndex == null) {
|
||||
setState(() {
|
||||
_selectedTariffIndex = 0;
|
||||
});
|
||||
}
|
||||
|
||||
if (state.status == TariffSheetStatus.failure && state.errorMessage != null) {
|
||||
ScaffoldMessenger.of(context).hideCurrentSnackBar();
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
@@ -82,6 +92,8 @@ class _TariffSheetState extends State<TariffSheet> {
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
final selectedIndex = _selectedTariffIndex ?? (state.tariffs.isNotEmpty ? 0 : null);
|
||||
|
||||
if (state.status == TariffSheetStatus.loading) {
|
||||
return Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
@@ -283,7 +295,7 @@ class _TariffSheetState extends State<TariffSheet> {
|
||||
'Далее ${tariff.drivePrice.toStringAsFixed(2)} ${tariff.currency}/мин.',
|
||||
'Минута на паузе ${tariff.pausePrice.toStringAsFixed(2)} ${tariff.currency}',
|
||||
],
|
||||
isSelected: _selectedTariffIndex == index,
|
||||
isSelected: selectedIndex == index,
|
||||
isInsurance: state.isInsurance,
|
||||
tariff: tariff,
|
||||
onTap: () {
|
||||
@@ -412,19 +424,20 @@ class _TariffSheetState extends State<TariffSheet> {
|
||||
height: 56,
|
||||
width: double.infinity,
|
||||
fontSize: 16,
|
||||
enabled: _selectedTariffIndex != null && (state.selectedCard != null || state.useBalance),
|
||||
onTap: (_selectedTariffIndex != null && (state.selectedCard != null || state.useBalance))
|
||||
enabled: selectedIndex != null && (state.selectedCard != null || state.useBalance),
|
||||
onTap: (selectedIndex != null && (state.selectedCard != null || state.useBalance))
|
||||
? () {
|
||||
context.read<TariffSheetBloc>().add(
|
||||
BookScooterPressed(
|
||||
widget.scooter.id,
|
||||
state.tariffs[_selectedTariffIndex!].id,
|
||||
state.tariffs[_selectedTariffIndex!].subscriptionId,
|
||||
state.tariffs[selectedIndex].id,
|
||||
state.tariffs[selectedIndex].subscriptionId,
|
||||
state.useBalance ? null : state.selectedCard?.id,
|
||||
state.useBalance,
|
||||
state.isInsurance
|
||||
)
|
||||
);
|
||||
context.read<MapBloc>().add(FetchActiveOrders());
|
||||
context.pushReplacement('/home/current-rides-sheet');
|
||||
}
|
||||
: null,
|
||||
|
||||
@@ -38,6 +38,8 @@ class FocusOnScooter extends ScooterEvent {
|
||||
class ClearMapPlacemarks extends ScooterEvent {}
|
||||
class ClearMapFocus extends ScooterEvent {}
|
||||
|
||||
class FetchActiveOrders extends ScooterEvent {}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -71,10 +71,10 @@ class _MapScreenState extends State<MapScreen> {
|
||||
BlocConsumer<MapBloc, ScooterState>(
|
||||
listenWhen: (previous, current) {
|
||||
return current.lastNotification !=
|
||||
previous.lastNotification ||
|
||||
previous.lastNotification ||
|
||||
current.flags != previous.flags ||
|
||||
previous.selectedScooterForFocus?.id
|
||||
!= current.selectedScooterForFocus?.id;
|
||||
previous.selectedScooterForFocus?.id !=
|
||||
current.selectedScooterForFocus?.id;
|
||||
},
|
||||
|
||||
listener: (context, state) {
|
||||
@@ -176,7 +176,8 @@ class _MapScreenState extends State<MapScreen> {
|
||||
|
||||
final reservedScooters = _buildScooterPlacemarks(
|
||||
scooters: state.reservedScooters ?? [],
|
||||
iconAsset: 'assets/icons/scooter_reserved_placemark_fill.png',
|
||||
iconAsset:
|
||||
'assets/icons/scooter_reserved_placemark_fill.png',
|
||||
isClickable: false,
|
||||
);
|
||||
|
||||
@@ -193,10 +194,10 @@ class _MapScreenState extends State<MapScreen> {
|
||||
},
|
||||
onCameraPositionChanged:
|
||||
(cameraPosition, reason, finished) {
|
||||
if (finished) {
|
||||
_fetchScooters();
|
||||
}
|
||||
},
|
||||
if (finished) {
|
||||
_fetchScooters();
|
||||
}
|
||||
},
|
||||
mapObjects: [
|
||||
...zonePolygons,
|
||||
...reservedScooters,
|
||||
@@ -210,7 +211,7 @@ class _MapScreenState extends State<MapScreen> {
|
||||
final clusteredPlacemarks = cluster.placemarks;
|
||||
final filtered = state.scooters.where((scooter) {
|
||||
return clusteredPlacemarks.any(
|
||||
(pm) => pm.mapId.value == scooter.id.toString(),
|
||||
(pm) => pm.mapId.value == scooter.id.toString(),
|
||||
);
|
||||
}).toList();
|
||||
_onMarkerTap(filtered);
|
||||
@@ -241,7 +242,7 @@ class _MapScreenState extends State<MapScreen> {
|
||||
|
||||
BlocBuilder<MapBloc, ScooterState>(
|
||||
buildWhen: (previous, current) =>
|
||||
previous.status != current.status,
|
||||
previous.status != current.status,
|
||||
builder: (context, state) {
|
||||
if (state.status == ScooterStatus.loading) {
|
||||
return const Positioned(
|
||||
@@ -368,6 +369,7 @@ class _MapScreenState extends State<MapScreen> {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _moveCameraToPoint(
|
||||
double lat,
|
||||
double lon, {
|
||||
@@ -401,17 +403,13 @@ class _MapScreenState extends State<MapScreen> {
|
||||
}
|
||||
if (flags.hasUnpaidOrder) {
|
||||
_showExistingNotification(
|
||||
child: UnpaidOrderNotificationCard(
|
||||
onClose: () => BotToast.cleanAll(),
|
||||
),
|
||||
child: UnpaidOrderNotificationCard(onClose: () => BotToast.cleanAll()),
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (flags.hasFine) {
|
||||
_showExistingNotification(
|
||||
child: FineNotificationCard(
|
||||
onClose: () => BotToast.cleanAll(),
|
||||
),
|
||||
child: FineNotificationCard(onClose: () => BotToast.cleanAll()),
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -567,7 +565,8 @@ class _MapScreenState extends State<MapScreen> {
|
||||
}) {
|
||||
return scooters.map((scooter) {
|
||||
return PlacemarkMapObject(
|
||||
mapId: MapObjectId('${isClickable ? "" : "reserved_"}${scooter.id}'), // уникальный ID для карты
|
||||
mapId: MapObjectId('${isClickable ? "" : "reserved_"}${scooter.id}'),
|
||||
// уникальный ID для карты
|
||||
point: Point(latitude: scooter.longitude, longitude: scooter.latitude),
|
||||
icon: PlacemarkIcon.single(
|
||||
PlacemarkIconStyle(
|
||||
@@ -595,7 +594,9 @@ class _MapScreenState extends State<MapScreen> {
|
||||
for (var polygonData in zone.geometry) {
|
||||
if (polygonData.isEmpty) continue;
|
||||
|
||||
var outerPoints = polygonData[0].map((p) => Point(latitude: p.latitude, longitude: p.longitude)).toList();
|
||||
var outerPoints = polygonData[0]
|
||||
.map((p) => Point(latitude: p.latitude, longitude: p.longitude))
|
||||
.toList();
|
||||
|
||||
var cleanPoints = <Point>[];
|
||||
for (var p in outerPoints) {
|
||||
@@ -619,12 +620,14 @@ class _MapScreenState extends State<MapScreen> {
|
||||
PolygonMapObject(
|
||||
mapId: const MapObjectId('global_inverse_mask'),
|
||||
polygon: Polygon(
|
||||
outerRing: const LinearRing(points: [
|
||||
Point(latitude: 85, longitude: -179.9),
|
||||
Point(latitude: 85, longitude: 179.9),
|
||||
Point(latitude: -85, longitude: 179.9),
|
||||
Point(latitude: -85, longitude: -179.9),
|
||||
]),
|
||||
outerRing: const LinearRing(
|
||||
points: [
|
||||
Point(latitude: 85, longitude: -179.9),
|
||||
Point(latitude: 85, longitude: 179.9),
|
||||
Point(latitude: -85, longitude: 179.9),
|
||||
Point(latitude: -85, longitude: -179.9),
|
||||
],
|
||||
),
|
||||
innerRings: driveOuterRings, // Вырезаем только зоны Drive
|
||||
),
|
||||
strokeWidth: 0,
|
||||
@@ -641,13 +644,17 @@ class _MapScreenState extends State<MapScreen> {
|
||||
// Стилизация в зависимости от типа зоны
|
||||
if (zone.type == "Drive") {
|
||||
borderColor = const Color(0xFF5ECD4C); // Зеленый бордюр
|
||||
fillColor = Colors.transparent; // Прозрачная внутри маски
|
||||
fillColor = Colors.transparent; // Прозрачная внутри маски
|
||||
} else if (zone.type == "NotDrive") {
|
||||
borderColor = const Color(0xFFEF4444); // Красный бордюр
|
||||
fillColor = const Color(0xFFEF4444).withOpacity(0.3); // Красная полупрозрачная заливка для наглядности внутри Drive
|
||||
fillColor = const Color(0xFFEF4444).withOpacity(
|
||||
0.3,
|
||||
); // Красная полупрозрачная заливка для наглядности внутри Drive
|
||||
} else {
|
||||
borderColor = const Color(0xFFA78BFA); // Фиолетовый бордюр (Парковка)
|
||||
fillColor = const Color(0xFFA78BFA).withOpacity(0.25); // Фиолетовая заливка
|
||||
fillColor = const Color(
|
||||
0xFFA78BFA,
|
||||
).withOpacity(0.25); // Фиолетовая заливка
|
||||
}
|
||||
|
||||
int polyIndex = 0;
|
||||
@@ -655,7 +662,9 @@ class _MapScreenState extends State<MapScreen> {
|
||||
if (polygonData.isEmpty) continue;
|
||||
|
||||
// Строим внешнее кольцо текущего полигона
|
||||
var outerPoints = polygonData[0].map((p) => Point(latitude: p.latitude, longitude: p.longitude)).toList();
|
||||
var outerPoints = polygonData[0]
|
||||
.map((p) => Point(latitude: p.latitude, longitude: p.longitude))
|
||||
.toList();
|
||||
if (outerPoints.first != outerPoints.last) {
|
||||
outerPoints.add(outerPoints.first);
|
||||
}
|
||||
@@ -664,7 +673,9 @@ class _MapScreenState extends State<MapScreen> {
|
||||
// Строим внутренние кольца (дыры), если они есть у этого полигона
|
||||
List<LinearRing> innerRings = [];
|
||||
for (int i = 1; i < polygonData.length; i++) {
|
||||
var innerPoints = polygonData[i].map((p) => Point(latitude: p.latitude, longitude: p.longitude)).toList();
|
||||
var innerPoints = polygonData[i]
|
||||
.map((p) => Point(latitude: p.latitude, longitude: p.longitude))
|
||||
.toList();
|
||||
if (innerPoints.isNotEmpty) {
|
||||
if (innerPoints.first != innerPoints.last) {
|
||||
innerPoints.add(innerPoints.first);
|
||||
@@ -677,10 +688,7 @@ class _MapScreenState extends State<MapScreen> {
|
||||
objects.add(
|
||||
PolygonMapObject(
|
||||
mapId: MapObjectId('zone_poly_${zone.type}_${zone.id}_$polyIndex'),
|
||||
polygon: Polygon(
|
||||
outerRing: outerRing,
|
||||
innerRings: innerRings,
|
||||
),
|
||||
polygon: Polygon(outerRing: outerRing, innerRings: innerRings),
|
||||
strokeColor: borderColor,
|
||||
strokeWidth: 2.0,
|
||||
fillColor: fillColor,
|
||||
@@ -707,7 +715,7 @@ class _MapScreenState extends State<MapScreen> {
|
||||
onPressed: () {
|
||||
context.read<MapBloc>().add(FetchProfileData());
|
||||
Scaffold.of(innerContext).openDrawer();
|
||||
},
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -721,10 +729,21 @@ class _MapScreenState extends State<MapScreen> {
|
||||
onPressed: () => context.push("/home/notifications"),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
_RoundButton(
|
||||
imagePath: 'assets/icons/scooter_placemark.png',
|
||||
onPressed: () => context.push("/home/current-rides-sheet"),
|
||||
)
|
||||
BlocBuilder<MapBloc, ScooterState>(
|
||||
buildWhen: (previous, current) =>
|
||||
previous.activeRidesCount != current.activeRidesCount,
|
||||
builder: (context, state) {
|
||||
return _RoundButton(
|
||||
imagePath: 'assets/icons/scooter_placemark.png',
|
||||
count: state.activeRidesCount ?? 0,
|
||||
onPressed: () {
|
||||
context.push("/home/current-rides-sheet").then((_) {
|
||||
context.read<MapBloc>().add(FetchActiveOrders());
|
||||
});
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -765,9 +784,7 @@ class _MapScreenState extends State<MapScreen> {
|
||||
}
|
||||
if (flags.hasFine) {
|
||||
_showExistingNotification(
|
||||
child: FineNotificationCard(
|
||||
onClose: () => BotToast.cleanAll(),
|
||||
),
|
||||
child: FineNotificationCard(onClose: () => BotToast.cleanAll()),
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -870,32 +887,63 @@ class _RoundIconButton extends StatelessWidget {
|
||||
class _RoundButton extends StatelessWidget {
|
||||
final String imagePath;
|
||||
final VoidCallback onPressed;
|
||||
final int count;
|
||||
|
||||
const _RoundButton({
|
||||
required this.imagePath,
|
||||
required this.onPressed,
|
||||
this.count = 0,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.darkBlue,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: GestureDetector(
|
||||
onTap: onPressed,
|
||||
child: Center(
|
||||
child: Image.asset(
|
||||
imagePath,
|
||||
width: 20,
|
||||
height: 20,
|
||||
fit: BoxFit.contain,
|
||||
color: Colors.white,
|
||||
return GestureDetector(
|
||||
onTap: onPressed,
|
||||
child: Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.darkBlue,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Center(
|
||||
child: Image.asset(
|
||||
imagePath,
|
||||
width: 20,
|
||||
height: 20,
|
||||
fit: BoxFit.contain,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (count > 0)
|
||||
Positioned(
|
||||
top: -4,
|
||||
right: -4,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(4),
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.redAccent,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
constraints: const BoxConstraints(minWidth: 18, minHeight: 18),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'$count',
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -929,10 +977,12 @@ void _showExistingNotification({required Widget child}) {
|
||||
duration: null, // не исчезает, пока пользователь не закроет
|
||||
toastBuilder: (_) {
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(top: 120), // тот же отступ, что в listener
|
||||
margin: const EdgeInsets.only(top: 120),
|
||||
// тот же отступ, что в listener
|
||||
child: Material(
|
||||
color: Colors.transparent,
|
||||
child: child, // PaymentNotificationCard / UnpaidOrderNotificationCard / FineNotificationCard
|
||||
child:
|
||||
child, // PaymentNotificationCard / UnpaidOrderNotificationCard / FineNotificationCard
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
@@ -30,13 +30,13 @@ class SupportScreen extends StatelessWidget {
|
||||
),
|
||||
const Divider(height: 1, color: Colors.white24),
|
||||
const SizedBox(height: 12),
|
||||
LinkRow(
|
||||
/*LinkRow(
|
||||
icon: 'assets/icons/whatsapp.png',
|
||||
title: 'WhatsApp',
|
||||
onTap: () => openLink('https://wa.me/375257110909'),
|
||||
),
|
||||
const Divider(height: 1, color: Colors.white24),
|
||||
const SizedBox(height: 12),
|
||||
const SizedBox(height: 12),*/
|
||||
LinkRow(
|
||||
icon: 'assets/icons/viber.png',
|
||||
title: 'Viber',
|
||||
|
||||
@@ -6,11 +6,11 @@ class MapSettingsModalState {
|
||||
final bool isRestrictedParkingZoneActive;
|
||||
|
||||
MapSettingsModalState({
|
||||
required this.isAllGeomarksActive,
|
||||
required this.isAllGeozonesActive,
|
||||
required this.isRestrictedDrivingZoneActive,
|
||||
required this.isParkingZoneActive,
|
||||
required this.isRestrictedParkingZoneActive,
|
||||
this.isAllGeomarksActive = true,
|
||||
this.isAllGeozonesActive = true,
|
||||
this.isRestrictedDrivingZoneActive = true,
|
||||
this.isParkingZoneActive = true,
|
||||
this.isRestrictedParkingZoneActive = true,
|
||||
});
|
||||
|
||||
MapSettingsModalState copyWith({
|
||||
|
||||
@@ -22,6 +22,7 @@ class ScooterState {
|
||||
final double balance;
|
||||
final UserCheckFlags flags;
|
||||
final ClientNotification? lastNotification;
|
||||
final int activeRidesCount;
|
||||
|
||||
ScooterState({
|
||||
this.scooters = const [],
|
||||
@@ -38,6 +39,7 @@ class ScooterState {
|
||||
this.balance = 999,
|
||||
this.flags = const UserCheckFlags(hasFine: false, hasUnpaidOrder: false, hasCard: false),
|
||||
this.lastNotification,
|
||||
this.activeRidesCount = 0,
|
||||
});
|
||||
|
||||
ScooterState copyWith({
|
||||
@@ -55,6 +57,7 @@ class ScooterState {
|
||||
double? balance,
|
||||
UserCheckFlags? flags,
|
||||
ClientNotification? lastNotification,
|
||||
int? activeRidesCount,
|
||||
}) {
|
||||
return ScooterState(
|
||||
scooters: scooters ?? this.scooters,
|
||||
@@ -71,6 +74,7 @@ class ScooterState {
|
||||
balance: balance ?? this.balance,
|
||||
flags: flags ?? this.flags,
|
||||
lastNotification: lastNotification ?? this.lastNotification,
|
||||
activeRidesCount: activeRidesCount ?? this.activeRidesCount,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ class TariffSheetState {
|
||||
this.status = TariffSheetStatus.initial,
|
||||
this.tariffs = const [],
|
||||
this.selectedCard,
|
||||
this.isInsurance = false,
|
||||
this.isInsurance = true,
|
||||
this.errorMessage,
|
||||
this.userBalance = 0,
|
||||
this.useBalance = false,
|
||||
|
||||
@@ -34,6 +34,7 @@ class MapBloc extends Bloc<ScooterEvent, ScooterState> {
|
||||
final LogoutUseCase logoutUseCase;
|
||||
final SplashBloc splashBloc;
|
||||
StreamSubscription<ClientNotification>? _notificationSubscription;
|
||||
Timer? _ordersTimer;
|
||||
|
||||
Future<List<Zone>>? _zonesFuture;
|
||||
|
||||
@@ -58,6 +59,7 @@ class MapBloc extends Bloc<ScooterEvent, ScooterState> {
|
||||
on<FocusOnScooter>(_onFocusOnScooter);
|
||||
on<ClearMapPlacemarks>(_onClearMapPlacemarks);
|
||||
on<ClearMapFocus>(_onClearMapFocus);
|
||||
on<FetchActiveOrders>(_onFetchActiveOrders);
|
||||
}
|
||||
|
||||
Future<List<Zone>> _getZones() async {
|
||||
@@ -344,4 +346,50 @@ class MapBloc extends Bloc<ScooterEvent, ScooterState> {
|
||||
selectedScooterForFocus: null,
|
||||
));
|
||||
}
|
||||
|
||||
void _startOrdersTimer() {
|
||||
_ordersTimer?.cancel();
|
||||
// Опрашиваем раз в 15 секунд, если есть активные поездки
|
||||
_ordersTimer = Timer.periodic(const Duration(seconds: 15), (_) {
|
||||
add(FetchActiveOrders());
|
||||
});
|
||||
}
|
||||
|
||||
void _stopOrdersTimer() {
|
||||
_ordersTimer?.cancel();
|
||||
_ordersTimer = null;
|
||||
}
|
||||
|
||||
Future<void> _onFetchActiveOrders(
|
||||
FetchActiveOrders event,
|
||||
Emitter<ScooterState> emit,
|
||||
) async {
|
||||
try {
|
||||
final result = await getClientOrdersUsecase();
|
||||
if (result is Success<List<ScooterOrder>>) {
|
||||
final activeOrders = result.data ?? [];
|
||||
final count = activeOrders.length;
|
||||
|
||||
// Управляем таймером в зависимости от наличия активных поездок
|
||||
if (count > 0 && (_ordersTimer == null || !_ordersTimer!.isActive)) {
|
||||
_startOrdersTimer();
|
||||
} else if (count == 0) {
|
||||
_stopOrdersTimer();
|
||||
}
|
||||
|
||||
emit(state.copyWith(
|
||||
activeRidesCount: count,
|
||||
reservedScooters: activeOrders.map((e) => e.scooter).toList(),
|
||||
));
|
||||
}
|
||||
} catch (e) {
|
||||
print("Error fetching active orders: $e");
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> close() {
|
||||
_stopOrdersTimer();
|
||||
return super.close();
|
||||
}
|
||||
}
|
||||
@@ -15,13 +15,7 @@ class MapSettingsModalBloc extends Bloc<MapSettingsModalEvent, MapSettingsModalS
|
||||
final SaveMapSettingsUsecase saveMapSettingsUsecase;
|
||||
|
||||
MapSettingsModalBloc(this.getMapSettingsUsecase, this.saveMapSettingsUsecase)
|
||||
: super(MapSettingsModalState(
|
||||
isAllGeomarksActive: true,
|
||||
isAllGeozonesActive: true,
|
||||
isParkingZoneActive: true,
|
||||
isRestrictedParkingZoneActive: true,
|
||||
isRestrictedDrivingZoneActive: true,
|
||||
)) {
|
||||
: super(MapSettingsModalState()) {
|
||||
on<AllGeozonesToggled>(_onAllGeozonesToggled);
|
||||
on<AllGeomarksToggled>(_onAllGeomarksToggled);
|
||||
on<ParkingZonesToggled>(_onParkingZonesToggled);
|
||||
|
||||
Reference in New Issue
Block a user