refactor(location): migrate module to Riverpod codegen + replace snackbars with dialogs

This commit is contained in:
2026-04-23 02:55:18 +02:00
parent 4fbdce3c8c
commit ac5219f389
23 changed files with 688 additions and 999 deletions

View File

@@ -1,12 +1,12 @@
import 'package:legacy_device_state/legacy_device_state.dart';
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:legacy_device_state/legacy_device_state.dart';
import 'package:legacy_ui/legacy_ui.dart';
import 'package:location/src/features/location/presentation/state/location_view_model.dart';
import 'package:location/src/features/location/presentation/state/location_view_state.dart';
import 'package:location/src/features/location/presentation/providers/location_controller.dart';
import 'package:location/src/features/location/presentation/providers/location_state.dart';
import 'package:location/src/features/location/presentation/widgets/location_map.dart';
import 'package:sf_localizations/sf_localizations.dart';
import 'package:sf_shared/sf_shared.dart';
class LocationScreen extends ConsumerWidget {
const LocationScreen({super.key});
@@ -14,100 +14,35 @@ class LocationScreen extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final asyncDeviceState = ref.watch(legacyDeviceViewModelProvider);
final asyncLocationState = ref.watch(locationViewModelProvider);
final asyncLocationState = ref.watch(locationControllerProvider);
ref.listen(
locationViewModelProvider.select((s) => s.value?.errorEvent),
(previous, next) {
if (next != null) {
final message = switch (next) {
LocationErrorEvent.geofenceCreate => context.translate(
I18n.errorGeofenceCreate,
),
LocationErrorEvent.geofenceUpdate => context.translate(
I18n.errorGeofenceUpdate,
),
LocationErrorEvent.geofenceDelete => context.translate(
I18n.errorGeofenceDelete,
),
LocationErrorEvent.frequentPlaceCreate => context.translate(
I18n.errorFrequentPlaceCreate,
),
LocationErrorEvent.frequentPlaceUpdate => context.translate(
I18n.errorFrequentPlaceUpdate,
),
LocationErrorEvent.frequentPlaceDelete => context.translate(
I18n.errorFrequentPlaceDelete,
),
LocationErrorEvent.positionHistory => context.translate(
I18n.errorPositionHistory,
),
LocationErrorEvent.locationFrequency => context.translate(
I18n.errorLocationFrequency,
),
};
showTopSnackbar(context, message: message, type: MessageType.error);
}
locationControllerProvider.select((s) => s.value?.displayErrorKey),
(previous, next) async {
if (next == null || next == previous) return;
await showErrorDialog(context, next);
ref.read(locationControllerProvider.notifier).clearErrorEvent();
},
);
ref.listen(
locationViewModelProvider.select((s) => s.value?.successMessage),
(previous, next) {
if (next != null) {
final message = switch (next) {
LocationSuccessEvent.geofenceCreated => context.translate(
I18n.geofenceCreated,
),
LocationSuccessEvent.geofenceUpdated => context.translate(
I18n.geofenceUpdated,
),
LocationSuccessEvent.geofenceDeleted => context.translate(
I18n.geofenceDeleted,
),
LocationSuccessEvent.frequentPlaceCreated => context.translate(
I18n.frequentPlaceCreated,
),
LocationSuccessEvent.frequentPlaceUpdated => context.translate(
I18n.frequentPlaceUpdated,
),
LocationSuccessEvent.frequentPlaceDeleted => context.translate(
I18n.frequentPlaceDeleted,
),
};
showTopSnackbar(
context,
message: message,
type: MessageType.success,
);
}
locationControllerProvider.select((s) => s.value?.displaySuccessKey),
(previous, next) async {
if (next == null || next == previous) return;
await showSuccessDialog(context, next);
ref.read(locationControllerProvider.notifier).clearSuccessEvent();
},
);
ref.listen(legacyDeviceViewModelProvider, (previous, next) {
ref.listen(locationControllerProvider, (previous, next) async {
if (next.hasError && previous != null && !previous.hasError) {
showTopSnackbar(
context,
message: context.translate(I18n.errorGeneric),
type: MessageType.error,
);
}
});
ref.listen(locationViewModelProvider, (previous, next) {
if (next.hasError && previous != null && !previous.hasError) {
showTopSnackbar(
context,
message: context.translate(I18n.errorGeneric),
type: MessageType.error,
);
await showErrorDialog(context, I18n.errorGeneric);
}
});
final deviceState = asyncDeviceState.value;
final locationState = asyncLocationState.value;
final isLoading = asyncDeviceState.isLoading &&
deviceState == null;
final isLoading = asyncDeviceState.isLoading && deviceState == null;
return LegacyPageLayout(
title: context.translate(I18n.mapTitle),
@@ -118,7 +53,7 @@ class LocationScreen extends ConsumerWidget {
? RefreshableErrorState(
onRefresh: () async {
ref.invalidate(legacyDeviceViewModelProvider);
ref.invalidate(locationViewModelProvider);
ref.invalidate(locationControllerProvider);
await ref.read(legacyDeviceViewModelProvider.future);
},
)
@@ -146,4 +81,3 @@ class LocationScreen extends ConsumerWidget {
);
}
}

View File

@@ -1,43 +1,36 @@
import 'dart:async';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:legacy_device_state/legacy_device_state.dart';
import 'package:location/src/core/data/models/create_frequent_place_request_dto.dart';
import 'package:location/src/core/data/models/create_geofence_request_dto.dart';
import 'package:location/src/core/data/models/frequent_places_response_dto.dart';
import 'package:location/src/core/data/models/update_frequent_place_request_dto.dart';
import 'package:location/src/core/data/models/update_geofence_request_dto.dart';
import 'package:location/src/core/domain/entities/geofence_entity.dart';
import 'package:location/src/core/domain/entities/frequent_place_entity.dart';
import 'package:location/src/core/domain/repositories/location_repository.dart';
import 'package:location/src/core/domain/entities/geofence_entity.dart';
import 'package:location/src/core/providers/location_repository_provider.dart';
import 'package:location/src/features/location/presentation/state/location_view_state.dart';
import 'package:location/src/features/location/presentation/providers/location_state.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:sf_shared/sf_shared.dart';
import 'package:sf_tracking/sf_tracking.dart';
import 'package:uuid/uuid.dart';
final locationViewModelProvider = AsyncNotifierProvider.autoDispose<
LocationViewModel,
LocationViewState>(LocationViewModel.new);
class LocationViewModel extends AsyncNotifier<LocationViewState> {
late LocationRepository _locationRepository;
late SfTrackingRepository _tracking;
part 'location_controller.g.dart';
@Riverpod(keepAlive: true)
class LocationController extends _$LocationController {
@override
Future<LocationViewState> build() async {
_locationRepository = ref.read(locationRepositoryProvider);
_tracking = ref.read(sfTrackingProvider);
Future<LocationState> build() async {
final repo = ref.read(locationRepositoryProvider);
final device = ref.watch(selectedDeviceProvider).value;
if (device == null) return const LocationViewState();
if (device == null) return const LocationState();
final results = await Future.wait([
_locationRepository.getGeofences(deviceId: device.id),
_locationRepository.getFrequentPlaces(deviceId: device.id),
repo.getGeofences(deviceId: device.id),
repo.getFrequentPlaces(deviceId: device.id),
]);
return LocationViewState(
return LocationState(
geofences: results[0] as List<GeofenceEntity>,
frequentPlaces: results[1] as List<FrequentPlaceEntity>,
);
@@ -57,7 +50,7 @@ class LocationViewModel extends AsyncNotifier<LocationViewState> {
current.copyWith(
isSubmitting: true,
errorEvent: null,
successMessage: null,
successEvent: null,
),
);
try {
@@ -75,18 +68,17 @@ class LocationViewModel extends AsyncNotifier<LocationViewState> {
groupId: device?.groupId,
deviceId: device?.id,
);
final created = await _locationRepository.createGeofence(
request: request,
);
if (!ref.mounted) return false;
final created = await ref
.read(locationRepositoryProvider)
.createGeofence(request: request);
unawaited(_tracking.legacyLocationGeofenceCreated());
unawaited(ref.read(sfTrackingProvider).legacyLocationGeofenceCreated());
state = AsyncData(
current.copyWith(
geofences: [...current.geofences, created],
isSubmitting: false,
successMessage: LocationSuccessEvent.geofenceCreated,
successEvent: LocationSuccessEvent.geofenceCreated,
),
);
return true;
@@ -110,7 +102,7 @@ class LocationViewModel extends AsyncNotifier<LocationViewState> {
current.copyWith(
isSubmitting: true,
errorEvent: null,
successMessage: null,
successEvent: null,
),
);
try {
@@ -122,12 +114,11 @@ class LocationViewModel extends AsyncNotifier<LocationViewState> {
longitude: longitude,
radius: radius,
);
final updated = await _locationRepository.updateGeofence(
request: request,
);
if (!ref.mounted) return false;
final updated = await ref
.read(locationRepositoryProvider)
.updateGeofence(request: request);
unawaited(_tracking.legacyLocationGeofenceUpdated());
unawaited(ref.read(sfTrackingProvider).legacyLocationGeofenceUpdated());
state = AsyncData(
current.copyWith(
@@ -135,7 +126,7 @@ class LocationViewModel extends AsyncNotifier<LocationViewState> {
.map((g) => g.id == id ? updated : g)
.toList(),
isSubmitting: false,
successMessage: LocationSuccessEvent.geofenceUpdated,
successEvent: LocationSuccessEvent.geofenceUpdated,
),
);
return true;
@@ -149,18 +140,17 @@ class LocationViewModel extends AsyncNotifier<LocationViewState> {
if (current == null) return false;
state = AsyncData(
current.copyWith(errorEvent: null, successMessage: null),
current.copyWith(errorEvent: null, successEvent: null),
);
try {
await _locationRepository.deleteGeofence(geofenceId: id);
if (!ref.mounted) return false;
await ref.read(locationRepositoryProvider).deleteGeofence(geofenceId: id);
unawaited(_tracking.legacyLocationGeofenceDeleted());
unawaited(ref.read(sfTrackingProvider).legacyLocationGeofenceDeleted());
state = AsyncData(
current.copyWith(
geofences: current.geofences.where((g) => g.id != id).toList(),
successMessage: LocationSuccessEvent.geofenceDeleted,
successEvent: LocationSuccessEvent.geofenceDeleted,
),
);
return true;
@@ -182,7 +172,7 @@ class LocationViewModel extends AsyncNotifier<LocationViewState> {
current.copyWith(
isSubmitting: true,
errorEvent: null,
successMessage: null,
successEvent: null,
),
);
try {
@@ -207,18 +197,19 @@ class LocationViewModel extends AsyncNotifier<LocationViewState> {
groupId: device?.groupId,
deviceId: device?.id,
);
final created = await _locationRepository.createFrequentPlace(
request: request,
);
if (!ref.mounted) return false;
final created = await ref
.read(locationRepositoryProvider)
.createFrequentPlace(request: request);
unawaited(_tracking.legacyLocationFrequentPlaceCreated());
unawaited(
ref.read(sfTrackingProvider).legacyLocationFrequentPlaceCreated(),
);
state = AsyncData(
current.copyWith(
frequentPlaces: [...current.frequentPlaces, created],
isSubmitting: false,
successMessage: LocationSuccessEvent.frequentPlaceCreated,
successEvent: LocationSuccessEvent.frequentPlaceCreated,
),
);
return true;
@@ -241,7 +232,7 @@ class LocationViewModel extends AsyncNotifier<LocationViewState> {
current.copyWith(
isSubmitting: true,
errorEvent: null,
successMessage: null,
successEvent: null,
),
);
try {
@@ -260,12 +251,13 @@ class LocationViewModel extends AsyncNotifier<LocationViewState> {
)
.toList(),
);
final updated = await _locationRepository.updateFrequentPlace(
request: request,
);
if (!ref.mounted) return false;
final updated = await ref
.read(locationRepositoryProvider)
.updateFrequentPlace(request: request);
unawaited(_tracking.legacyLocationFrequentPlaceUpdated());
unawaited(
ref.read(sfTrackingProvider).legacyLocationFrequentPlaceUpdated(),
);
state = AsyncData(
current.copyWith(
@@ -273,7 +265,7 @@ class LocationViewModel extends AsyncNotifier<LocationViewState> {
.map((f) => f.id == id ? updated : f)
.toList(),
isSubmitting: false,
successMessage: LocationSuccessEvent.frequentPlaceUpdated,
successEvent: LocationSuccessEvent.frequentPlaceUpdated,
),
);
return true;
@@ -287,19 +279,23 @@ class LocationViewModel extends AsyncNotifier<LocationViewState> {
if (current == null) return false;
state = AsyncData(
current.copyWith(errorEvent: null, successMessage: null),
current.copyWith(errorEvent: null, successEvent: null),
);
try {
await _locationRepository.deleteFrequentPlace(frequentPlaceId: id);
if (!ref.mounted) return false;
await ref
.read(locationRepositoryProvider)
.deleteFrequentPlace(frequentPlaceId: id);
unawaited(_tracking.legacyLocationFrequentPlaceDeleted());
unawaited(
ref.read(sfTrackingProvider).legacyLocationFrequentPlaceDeleted(),
);
state = AsyncData(
current.copyWith(
frequentPlaces:
current.frequentPlaces.where((f) => f.id != id).toList(),
successMessage: LocationSuccessEvent.frequentPlaceDeleted,
frequentPlaces: current.frequentPlaces
.where((f) => f.id != id)
.toList(),
successEvent: LocationSuccessEvent.frequentPlaceDeleted,
),
);
return true;
@@ -321,14 +317,15 @@ class LocationViewModel extends AsyncNotifier<LocationViewState> {
current.copyWith(isLoadingHistory: true, errorEvent: null),
);
try {
final positions = await _locationRepository.getPositionHistory(
deviceIdentificator: device.identificator,
from: from,
to: to,
);
if (!ref.mounted) return;
final positions = await ref
.read(locationRepositoryProvider)
.getPositionHistory(
deviceIdentificator: device.identificator,
from: from,
to: to,
);
unawaited(_tracking.legacyLocationHistoryLoaded());
unawaited(ref.read(sfTrackingProvider).legacyLocationHistoryLoaded());
state = AsyncData(
current.copyWith(
@@ -338,7 +335,6 @@ class LocationViewModel extends AsyncNotifier<LocationViewState> {
),
);
} catch (e) {
if (!ref.mounted) return;
state = AsyncData(
current.copyWith(
isLoadingHistory: false,
@@ -353,7 +349,7 @@ class LocationViewModel extends AsyncNotifier<LocationViewState> {
if (current == null) return;
if (current.positionHistory.isNotEmpty) {
unawaited(_tracking.legacyLocationHistoryCleared());
unawaited(ref.read(sfTrackingProvider).legacyLocationHistoryCleared());
}
state = AsyncData(
current.copyWith(positionHistory: [], showRouteTrail: false),
@@ -365,7 +361,11 @@ class LocationViewModel extends AsyncNotifier<LocationViewState> {
if (current == null) return;
final newVisible = !current.showRouteTrail;
unawaited(_tracking.legacyLocationMapRouteTrailToggled(newVisible));
unawaited(
ref.read(sfTrackingProvider).legacyLocationMapRouteTrailToggled(
newVisible,
),
);
state = AsyncData(current.copyWith(showRouteTrail: newVisible));
}
@@ -388,10 +388,11 @@ class LocationViewModel extends AsyncNotifier<LocationViewState> {
updatedSettings: updatedSettings,
);
if (!ref.mounted) return false;
ref.syncDeviceSettings(device, updatedSettings);
unawaited(_tracking.legacyLocationFrequencyUpdated(frequency));
unawaited(
ref.read(sfTrackingProvider).legacyLocationFrequencyUpdated(frequency),
);
state = AsyncData(current.copyWith(isSubmitting: false));
return true;
@@ -400,8 +401,19 @@ class LocationViewModel extends AsyncNotifier<LocationViewState> {
}
}
void clearErrorEvent() {
final current = state.value;
if (current == null) return;
state = AsyncData(current.copyWith(errorEvent: null));
}
void clearSuccessEvent() {
final current = state.value;
if (current == null) return;
state = AsyncData(current.copyWith(successEvent: null));
}
bool _handleErrorEvent(LocationErrorEvent event) {
if (!ref.mounted) return false;
final current = state.value;
if (current == null) return false;
state = AsyncData(

View File

@@ -0,0 +1,56 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'location_controller.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint, type=warning
@ProviderFor(LocationController)
const locationControllerProvider = LocationControllerProvider._();
final class LocationControllerProvider
extends $AsyncNotifierProvider<LocationController, LocationState> {
const LocationControllerProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'locationControllerProvider',
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$locationControllerHash();
@$internal
@override
LocationController create() => LocationController();
}
String _$locationControllerHash() =>
r'43534cd92b74ec5fabc9a43c6ef8398846855cf4';
abstract class _$LocationController extends $AsyncNotifier<LocationState> {
FutureOr<LocationState> build();
@$mustCallSuper
@override
void runBuild() {
final created = build();
final ref = this.ref as $Ref<AsyncValue<LocationState>, LocationState>;
final element =
ref.element
as $ClassProviderElement<
AnyNotifier<AsyncValue<LocationState>, LocationState>,
AsyncValue<LocationState>,
Object?,
Object?
>;
element.handleValue(ref, created);
}
}

View File

@@ -0,0 +1,11 @@
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'location_list_filter_controller.g.dart';
@riverpod
class LocationListFilter extends _$LocationListFilter {
@override
String? build() => null;
void select(String? type) => state = type;
}

View File

@@ -0,0 +1,64 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'location_list_filter_controller.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint, type=warning
@ProviderFor(LocationListFilter)
const locationListFilterProvider = LocationListFilterProvider._();
final class LocationListFilterProvider
extends $NotifierProvider<LocationListFilter, String?> {
const LocationListFilterProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'locationListFilterProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$locationListFilterHash();
@$internal
@override
LocationListFilter create() => LocationListFilter();
/// {@macro riverpod.override_with_value}
Override overrideWithValue(String? value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<String?>(value),
);
}
}
String _$locationListFilterHash() =>
r'c55f4584aa74592c51b88d3a05cee95d8337466f';
abstract class _$LocationListFilter extends $Notifier<String?> {
String? build();
@$mustCallSuper
@override
void runBuild() {
final created = build();
final ref = this.ref as $Ref<String?, String?>;
final element =
ref.element
as $ClassProviderElement<
AnyNotifier<String?, String?>,
String?,
Object?,
Object?
>;
element.handleValue(ref, created);
}
}

View File

@@ -1,29 +1,27 @@
import 'dart:async';
import 'package:legacy_device_state/legacy_device_state.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:latlong2/latlong.dart';
import 'package:location/src/core/domain/entities/geofence_entity.dart';
import 'package:legacy_device_state/legacy_device_state.dart';
import 'package:location/src/core/domain/entities/frequent_place_entity.dart';
import 'package:location/src/features/location/presentation/state/location_map_view_state.dart';
import 'package:location/src/core/domain/entities/geofence_entity.dart';
import 'package:location/src/features/location/presentation/providers/location_map_state.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:sf_tracking/sf_tracking.dart';
final locationMapViewModelProvider =
NotifierProvider.autoDispose<LocationMapViewModel, LocationMapViewState>(
LocationMapViewModel.new,
);
part 'location_map_controller.g.dart';
class LocationMapViewModel extends Notifier<LocationMapViewState> {
@riverpod
class LocationMapController extends _$LocationMapController {
late final SfTrackingRepository _tracking;
Timer? _zoomDebounce;
static const Duration _zoomDebounceDelay = Duration(seconds: 1);
@override
LocationMapViewState build() {
LocationMapState build() {
_tracking = ref.read(sfTrackingProvider);
ref.onDispose(() => _zoomDebounce?.cancel());
return const LocationMapViewState();
return const LocationMapState();
}
void toggleGeofences() {

View File

@@ -0,0 +1,64 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'location_map_controller.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint, type=warning
@ProviderFor(LocationMapController)
const locationMapControllerProvider = LocationMapControllerProvider._();
final class LocationMapControllerProvider
extends $NotifierProvider<LocationMapController, LocationMapState> {
const LocationMapControllerProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'locationMapControllerProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$locationMapControllerHash();
@$internal
@override
LocationMapController create() => LocationMapController();
/// {@macro riverpod.override_with_value}
Override overrideWithValue(LocationMapState value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<LocationMapState>(value),
);
}
}
String _$locationMapControllerHash() =>
r'c6eea4cec7a9a66546e9b66baf384edbb6e320f2';
abstract class _$LocationMapController extends $Notifier<LocationMapState> {
LocationMapState build();
@$mustCallSuper
@override
void runBuild() {
final created = build();
final ref = this.ref as $Ref<LocationMapState, LocationMapState>;
final element =
ref.element
as $ClassProviderElement<
AnyNotifier<LocationMapState, LocationMapState>,
LocationMapState,
Object?,
Object?
>;
element.handleValue(ref, created);
}
}

View File

@@ -1,18 +1,18 @@
import 'package:legacy_device_state/legacy_device_state.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:latlong2/latlong.dart';
import 'package:location/src/core/domain/entities/geofence_entity.dart';
import 'package:legacy_device_state/legacy_device_state.dart';
import 'package:location/src/core/domain/entities/frequent_place_entity.dart';
import 'package:location/src/core/domain/entities/geofence_entity.dart';
part 'location_map_view_state.freezed.dart';
part 'location_map_state.freezed.dart';
const _defaultZoom = 17.0;
enum PlacingMode { none, geofence, frequentPlace }
@freezed
abstract class LocationMapViewState with _$LocationMapViewState {
const factory LocationMapViewState({
abstract class LocationMapState with _$LocationMapState {
const factory LocationMapState({
@Default(true) bool showGeofences,
@Default(true) bool showFrequentPlaces,
@Default(PlacingMode.none) PlacingMode placingMode,
@@ -27,5 +27,5 @@ abstract class LocationMapViewState with _$LocationMapViewState {
@Default(false) bool actionsExpanded,
@Default(false) bool frequencyExpanded,
@Default(_defaultZoom) double mapZoom,
}) = _LocationMapViewState;
}) = _LocationMapState;
}

View File

@@ -3,7 +3,7 @@
// ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
part of 'location_map_view_state.dart';
part of 'location_map_state.dart';
// **************************************************************************
// FreezedGenerator
@@ -12,20 +12,20 @@ part of 'location_map_view_state.dart';
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$LocationMapViewState {
mixin _$LocationMapState {
bool get showGeofences; bool get showFrequentPlaces; PlacingMode get placingMode; bool get adjustingRadius; double get previewRadius; LatLng? get previewPoint; GeofenceEntity? get selectedGeofence; GeofenceEntity? get editingGeofence; FrequentPlaceEntity? get selectedFrequentPlace; PositionEntity? get selectedHistoryPosition; bool get isFollowing; bool get actionsExpanded; bool get frequencyExpanded; double get mapZoom;
/// Create a copy of LocationMapViewState
/// Create a copy of LocationMapState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$LocationMapViewStateCopyWith<LocationMapViewState> get copyWith => _$LocationMapViewStateCopyWithImpl<LocationMapViewState>(this as LocationMapViewState, _$identity);
$LocationMapStateCopyWith<LocationMapState> get copyWith => _$LocationMapStateCopyWithImpl<LocationMapState>(this as LocationMapState, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is LocationMapViewState&&(identical(other.showGeofences, showGeofences) || other.showGeofences == showGeofences)&&(identical(other.showFrequentPlaces, showFrequentPlaces) || other.showFrequentPlaces == showFrequentPlaces)&&(identical(other.placingMode, placingMode) || other.placingMode == placingMode)&&(identical(other.adjustingRadius, adjustingRadius) || other.adjustingRadius == adjustingRadius)&&(identical(other.previewRadius, previewRadius) || other.previewRadius == previewRadius)&&(identical(other.previewPoint, previewPoint) || other.previewPoint == previewPoint)&&(identical(other.selectedGeofence, selectedGeofence) || other.selectedGeofence == selectedGeofence)&&(identical(other.editingGeofence, editingGeofence) || other.editingGeofence == editingGeofence)&&(identical(other.selectedFrequentPlace, selectedFrequentPlace) || other.selectedFrequentPlace == selectedFrequentPlace)&&(identical(other.selectedHistoryPosition, selectedHistoryPosition) || other.selectedHistoryPosition == selectedHistoryPosition)&&(identical(other.isFollowing, isFollowing) || other.isFollowing == isFollowing)&&(identical(other.actionsExpanded, actionsExpanded) || other.actionsExpanded == actionsExpanded)&&(identical(other.frequencyExpanded, frequencyExpanded) || other.frequencyExpanded == frequencyExpanded)&&(identical(other.mapZoom, mapZoom) || other.mapZoom == mapZoom));
return identical(this, other) || (other.runtimeType == runtimeType&&other is LocationMapState&&(identical(other.showGeofences, showGeofences) || other.showGeofences == showGeofences)&&(identical(other.showFrequentPlaces, showFrequentPlaces) || other.showFrequentPlaces == showFrequentPlaces)&&(identical(other.placingMode, placingMode) || other.placingMode == placingMode)&&(identical(other.adjustingRadius, adjustingRadius) || other.adjustingRadius == adjustingRadius)&&(identical(other.previewRadius, previewRadius) || other.previewRadius == previewRadius)&&(identical(other.previewPoint, previewPoint) || other.previewPoint == previewPoint)&&(identical(other.selectedGeofence, selectedGeofence) || other.selectedGeofence == selectedGeofence)&&(identical(other.editingGeofence, editingGeofence) || other.editingGeofence == editingGeofence)&&(identical(other.selectedFrequentPlace, selectedFrequentPlace) || other.selectedFrequentPlace == selectedFrequentPlace)&&(identical(other.selectedHistoryPosition, selectedHistoryPosition) || other.selectedHistoryPosition == selectedHistoryPosition)&&(identical(other.isFollowing, isFollowing) || other.isFollowing == isFollowing)&&(identical(other.actionsExpanded, actionsExpanded) || other.actionsExpanded == actionsExpanded)&&(identical(other.frequencyExpanded, frequencyExpanded) || other.frequencyExpanded == frequencyExpanded)&&(identical(other.mapZoom, mapZoom) || other.mapZoom == mapZoom));
}
@@ -34,15 +34,15 @@ int get hashCode => Object.hash(runtimeType,showGeofences,showFrequentPlaces,pla
@override
String toString() {
return 'LocationMapViewState(showGeofences: $showGeofences, showFrequentPlaces: $showFrequentPlaces, placingMode: $placingMode, adjustingRadius: $adjustingRadius, previewRadius: $previewRadius, previewPoint: $previewPoint, selectedGeofence: $selectedGeofence, editingGeofence: $editingGeofence, selectedFrequentPlace: $selectedFrequentPlace, selectedHistoryPosition: $selectedHistoryPosition, isFollowing: $isFollowing, actionsExpanded: $actionsExpanded, frequencyExpanded: $frequencyExpanded, mapZoom: $mapZoom)';
return 'LocationMapState(showGeofences: $showGeofences, showFrequentPlaces: $showFrequentPlaces, placingMode: $placingMode, adjustingRadius: $adjustingRadius, previewRadius: $previewRadius, previewPoint: $previewPoint, selectedGeofence: $selectedGeofence, editingGeofence: $editingGeofence, selectedFrequentPlace: $selectedFrequentPlace, selectedHistoryPosition: $selectedHistoryPosition, isFollowing: $isFollowing, actionsExpanded: $actionsExpanded, frequencyExpanded: $frequencyExpanded, mapZoom: $mapZoom)';
}
}
/// @nodoc
abstract mixin class $LocationMapViewStateCopyWith<$Res> {
factory $LocationMapViewStateCopyWith(LocationMapViewState value, $Res Function(LocationMapViewState) _then) = _$LocationMapViewStateCopyWithImpl;
abstract mixin class $LocationMapStateCopyWith<$Res> {
factory $LocationMapStateCopyWith(LocationMapState value, $Res Function(LocationMapState) _then) = _$LocationMapStateCopyWithImpl;
@useResult
$Res call({
bool showGeofences, bool showFrequentPlaces, PlacingMode placingMode, bool adjustingRadius, double previewRadius, LatLng? previewPoint, GeofenceEntity? selectedGeofence, GeofenceEntity? editingGeofence, FrequentPlaceEntity? selectedFrequentPlace, PositionEntity? selectedHistoryPosition, bool isFollowing, bool actionsExpanded, bool frequencyExpanded, double mapZoom
@@ -53,14 +53,14 @@ $GeofenceEntityCopyWith<$Res>? get selectedGeofence;$GeofenceEntityCopyWith<$Res
}
/// @nodoc
class _$LocationMapViewStateCopyWithImpl<$Res>
implements $LocationMapViewStateCopyWith<$Res> {
_$LocationMapViewStateCopyWithImpl(this._self, this._then);
class _$LocationMapStateCopyWithImpl<$Res>
implements $LocationMapStateCopyWith<$Res> {
_$LocationMapStateCopyWithImpl(this._self, this._then);
final LocationMapViewState _self;
final $Res Function(LocationMapViewState) _then;
final LocationMapState _self;
final $Res Function(LocationMapState) _then;
/// Create a copy of LocationMapViewState
/// Create a copy of LocationMapState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? showGeofences = null,Object? showFrequentPlaces = null,Object? placingMode = null,Object? adjustingRadius = null,Object? previewRadius = null,Object? previewPoint = freezed,Object? selectedGeofence = freezed,Object? editingGeofence = freezed,Object? selectedFrequentPlace = freezed,Object? selectedHistoryPosition = freezed,Object? isFollowing = null,Object? actionsExpanded = null,Object? frequencyExpanded = null,Object? mapZoom = null,}) {
return _then(_self.copyWith(
@@ -81,7 +81,7 @@ as bool,mapZoom: null == mapZoom ? _self.mapZoom : mapZoom // ignore: cast_nulla
as double,
));
}
/// Create a copy of LocationMapViewState
/// Create a copy of LocationMapState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
@@ -93,7 +93,7 @@ $GeofenceEntityCopyWith<$Res>? get selectedGeofence {
return $GeofenceEntityCopyWith<$Res>(_self.selectedGeofence!, (value) {
return _then(_self.copyWith(selectedGeofence: value));
});
}/// Create a copy of LocationMapViewState
}/// Create a copy of LocationMapState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
@@ -105,7 +105,7 @@ $GeofenceEntityCopyWith<$Res>? get editingGeofence {
return $GeofenceEntityCopyWith<$Res>(_self.editingGeofence!, (value) {
return _then(_self.copyWith(editingGeofence: value));
});
}/// Create a copy of LocationMapViewState
}/// Create a copy of LocationMapState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
@@ -117,7 +117,7 @@ $FrequentPlaceEntityCopyWith<$Res>? get selectedFrequentPlace {
return $FrequentPlaceEntityCopyWith<$Res>(_self.selectedFrequentPlace!, (value) {
return _then(_self.copyWith(selectedFrequentPlace: value));
});
}/// Create a copy of LocationMapViewState
}/// Create a copy of LocationMapState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
@@ -133,8 +133,8 @@ $PositionEntityCopyWith<$Res>? get selectedHistoryPosition {
}
/// Adds pattern-matching-related methods to [LocationMapViewState].
extension LocationMapViewStatePatterns on LocationMapViewState {
/// Adds pattern-matching-related methods to [LocationMapState].
extension LocationMapStatePatterns on LocationMapState {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
@@ -147,10 +147,10 @@ extension LocationMapViewStatePatterns on LocationMapViewState {
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _LocationMapViewState value)? $default,{required TResult orElse(),}){
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _LocationMapState value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _LocationMapViewState() when $default != null:
case _LocationMapState() when $default != null:
return $default(_that);case _:
return orElse();
@@ -169,10 +169,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _LocationMapViewState value) $default,){
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _LocationMapState value) $default,){
final _that = this;
switch (_that) {
case _LocationMapViewState():
case _LocationMapState():
return $default(_that);case _:
throw StateError('Unexpected subclass');
@@ -190,10 +190,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _LocationMapViewState value)? $default,){
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _LocationMapState value)? $default,){
final _that = this;
switch (_that) {
case _LocationMapViewState() when $default != null:
case _LocationMapState() when $default != null:
return $default(_that);case _:
return null;
@@ -213,7 +213,7 @@ return $default(_that);case _:
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( bool showGeofences, bool showFrequentPlaces, PlacingMode placingMode, bool adjustingRadius, double previewRadius, LatLng? previewPoint, GeofenceEntity? selectedGeofence, GeofenceEntity? editingGeofence, FrequentPlaceEntity? selectedFrequentPlace, PositionEntity? selectedHistoryPosition, bool isFollowing, bool actionsExpanded, bool frequencyExpanded, double mapZoom)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _LocationMapViewState() when $default != null:
case _LocationMapState() when $default != null:
return $default(_that.showGeofences,_that.showFrequentPlaces,_that.placingMode,_that.adjustingRadius,_that.previewRadius,_that.previewPoint,_that.selectedGeofence,_that.editingGeofence,_that.selectedFrequentPlace,_that.selectedHistoryPosition,_that.isFollowing,_that.actionsExpanded,_that.frequencyExpanded,_that.mapZoom);case _:
return orElse();
@@ -234,7 +234,7 @@ return $default(_that.showGeofences,_that.showFrequentPlaces,_that.placingMode,_
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( bool showGeofences, bool showFrequentPlaces, PlacingMode placingMode, bool adjustingRadius, double previewRadius, LatLng? previewPoint, GeofenceEntity? selectedGeofence, GeofenceEntity? editingGeofence, FrequentPlaceEntity? selectedFrequentPlace, PositionEntity? selectedHistoryPosition, bool isFollowing, bool actionsExpanded, bool frequencyExpanded, double mapZoom) $default,) {final _that = this;
switch (_that) {
case _LocationMapViewState():
case _LocationMapState():
return $default(_that.showGeofences,_that.showFrequentPlaces,_that.placingMode,_that.adjustingRadius,_that.previewRadius,_that.previewPoint,_that.selectedGeofence,_that.editingGeofence,_that.selectedFrequentPlace,_that.selectedHistoryPosition,_that.isFollowing,_that.actionsExpanded,_that.frequencyExpanded,_that.mapZoom);case _:
throw StateError('Unexpected subclass');
@@ -254,7 +254,7 @@ return $default(_that.showGeofences,_that.showFrequentPlaces,_that.placingMode,_
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( bool showGeofences, bool showFrequentPlaces, PlacingMode placingMode, bool adjustingRadius, double previewRadius, LatLng? previewPoint, GeofenceEntity? selectedGeofence, GeofenceEntity? editingGeofence, FrequentPlaceEntity? selectedFrequentPlace, PositionEntity? selectedHistoryPosition, bool isFollowing, bool actionsExpanded, bool frequencyExpanded, double mapZoom)? $default,) {final _that = this;
switch (_that) {
case _LocationMapViewState() when $default != null:
case _LocationMapState() when $default != null:
return $default(_that.showGeofences,_that.showFrequentPlaces,_that.placingMode,_that.adjustingRadius,_that.previewRadius,_that.previewPoint,_that.selectedGeofence,_that.editingGeofence,_that.selectedFrequentPlace,_that.selectedHistoryPosition,_that.isFollowing,_that.actionsExpanded,_that.frequencyExpanded,_that.mapZoom);case _:
return null;
@@ -266,8 +266,8 @@ return $default(_that.showGeofences,_that.showFrequentPlaces,_that.placingMode,_
/// @nodoc
class _LocationMapViewState implements LocationMapViewState {
const _LocationMapViewState({this.showGeofences = true, this.showFrequentPlaces = true, this.placingMode = PlacingMode.none, this.adjustingRadius = false, this.previewRadius = 200.0, this.previewPoint, this.selectedGeofence, this.editingGeofence, this.selectedFrequentPlace, this.selectedHistoryPosition, this.isFollowing = false, this.actionsExpanded = false, this.frequencyExpanded = false, this.mapZoom = _defaultZoom});
class _LocationMapState implements LocationMapState {
const _LocationMapState({this.showGeofences = true, this.showFrequentPlaces = true, this.placingMode = PlacingMode.none, this.adjustingRadius = false, this.previewRadius = 200.0, this.previewPoint, this.selectedGeofence, this.editingGeofence, this.selectedFrequentPlace, this.selectedHistoryPosition, this.isFollowing = false, this.actionsExpanded = false, this.frequencyExpanded = false, this.mapZoom = _defaultZoom});
@override@JsonKey() final bool showGeofences;
@@ -285,17 +285,17 @@ class _LocationMapViewState implements LocationMapViewState {
@override@JsonKey() final bool frequencyExpanded;
@override@JsonKey() final double mapZoom;
/// Create a copy of LocationMapViewState
/// Create a copy of LocationMapState
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$LocationMapViewStateCopyWith<_LocationMapViewState> get copyWith => __$LocationMapViewStateCopyWithImpl<_LocationMapViewState>(this, _$identity);
_$LocationMapStateCopyWith<_LocationMapState> get copyWith => __$LocationMapStateCopyWithImpl<_LocationMapState>(this, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _LocationMapViewState&&(identical(other.showGeofences, showGeofences) || other.showGeofences == showGeofences)&&(identical(other.showFrequentPlaces, showFrequentPlaces) || other.showFrequentPlaces == showFrequentPlaces)&&(identical(other.placingMode, placingMode) || other.placingMode == placingMode)&&(identical(other.adjustingRadius, adjustingRadius) || other.adjustingRadius == adjustingRadius)&&(identical(other.previewRadius, previewRadius) || other.previewRadius == previewRadius)&&(identical(other.previewPoint, previewPoint) || other.previewPoint == previewPoint)&&(identical(other.selectedGeofence, selectedGeofence) || other.selectedGeofence == selectedGeofence)&&(identical(other.editingGeofence, editingGeofence) || other.editingGeofence == editingGeofence)&&(identical(other.selectedFrequentPlace, selectedFrequentPlace) || other.selectedFrequentPlace == selectedFrequentPlace)&&(identical(other.selectedHistoryPosition, selectedHistoryPosition) || other.selectedHistoryPosition == selectedHistoryPosition)&&(identical(other.isFollowing, isFollowing) || other.isFollowing == isFollowing)&&(identical(other.actionsExpanded, actionsExpanded) || other.actionsExpanded == actionsExpanded)&&(identical(other.frequencyExpanded, frequencyExpanded) || other.frequencyExpanded == frequencyExpanded)&&(identical(other.mapZoom, mapZoom) || other.mapZoom == mapZoom));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _LocationMapState&&(identical(other.showGeofences, showGeofences) || other.showGeofences == showGeofences)&&(identical(other.showFrequentPlaces, showFrequentPlaces) || other.showFrequentPlaces == showFrequentPlaces)&&(identical(other.placingMode, placingMode) || other.placingMode == placingMode)&&(identical(other.adjustingRadius, adjustingRadius) || other.adjustingRadius == adjustingRadius)&&(identical(other.previewRadius, previewRadius) || other.previewRadius == previewRadius)&&(identical(other.previewPoint, previewPoint) || other.previewPoint == previewPoint)&&(identical(other.selectedGeofence, selectedGeofence) || other.selectedGeofence == selectedGeofence)&&(identical(other.editingGeofence, editingGeofence) || other.editingGeofence == editingGeofence)&&(identical(other.selectedFrequentPlace, selectedFrequentPlace) || other.selectedFrequentPlace == selectedFrequentPlace)&&(identical(other.selectedHistoryPosition, selectedHistoryPosition) || other.selectedHistoryPosition == selectedHistoryPosition)&&(identical(other.isFollowing, isFollowing) || other.isFollowing == isFollowing)&&(identical(other.actionsExpanded, actionsExpanded) || other.actionsExpanded == actionsExpanded)&&(identical(other.frequencyExpanded, frequencyExpanded) || other.frequencyExpanded == frequencyExpanded)&&(identical(other.mapZoom, mapZoom) || other.mapZoom == mapZoom));
}
@@ -304,15 +304,15 @@ int get hashCode => Object.hash(runtimeType,showGeofences,showFrequentPlaces,pla
@override
String toString() {
return 'LocationMapViewState(showGeofences: $showGeofences, showFrequentPlaces: $showFrequentPlaces, placingMode: $placingMode, adjustingRadius: $adjustingRadius, previewRadius: $previewRadius, previewPoint: $previewPoint, selectedGeofence: $selectedGeofence, editingGeofence: $editingGeofence, selectedFrequentPlace: $selectedFrequentPlace, selectedHistoryPosition: $selectedHistoryPosition, isFollowing: $isFollowing, actionsExpanded: $actionsExpanded, frequencyExpanded: $frequencyExpanded, mapZoom: $mapZoom)';
return 'LocationMapState(showGeofences: $showGeofences, showFrequentPlaces: $showFrequentPlaces, placingMode: $placingMode, adjustingRadius: $adjustingRadius, previewRadius: $previewRadius, previewPoint: $previewPoint, selectedGeofence: $selectedGeofence, editingGeofence: $editingGeofence, selectedFrequentPlace: $selectedFrequentPlace, selectedHistoryPosition: $selectedHistoryPosition, isFollowing: $isFollowing, actionsExpanded: $actionsExpanded, frequencyExpanded: $frequencyExpanded, mapZoom: $mapZoom)';
}
}
/// @nodoc
abstract mixin class _$LocationMapViewStateCopyWith<$Res> implements $LocationMapViewStateCopyWith<$Res> {
factory _$LocationMapViewStateCopyWith(_LocationMapViewState value, $Res Function(_LocationMapViewState) _then) = __$LocationMapViewStateCopyWithImpl;
abstract mixin class _$LocationMapStateCopyWith<$Res> implements $LocationMapStateCopyWith<$Res> {
factory _$LocationMapStateCopyWith(_LocationMapState value, $Res Function(_LocationMapState) _then) = __$LocationMapStateCopyWithImpl;
@override @useResult
$Res call({
bool showGeofences, bool showFrequentPlaces, PlacingMode placingMode, bool adjustingRadius, double previewRadius, LatLng? previewPoint, GeofenceEntity? selectedGeofence, GeofenceEntity? editingGeofence, FrequentPlaceEntity? selectedFrequentPlace, PositionEntity? selectedHistoryPosition, bool isFollowing, bool actionsExpanded, bool frequencyExpanded, double mapZoom
@@ -323,17 +323,17 @@ $Res call({
}
/// @nodoc
class __$LocationMapViewStateCopyWithImpl<$Res>
implements _$LocationMapViewStateCopyWith<$Res> {
__$LocationMapViewStateCopyWithImpl(this._self, this._then);
class __$LocationMapStateCopyWithImpl<$Res>
implements _$LocationMapStateCopyWith<$Res> {
__$LocationMapStateCopyWithImpl(this._self, this._then);
final _LocationMapViewState _self;
final $Res Function(_LocationMapViewState) _then;
final _LocationMapState _self;
final $Res Function(_LocationMapState) _then;
/// Create a copy of LocationMapViewState
/// Create a copy of LocationMapState
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? showGeofences = null,Object? showFrequentPlaces = null,Object? placingMode = null,Object? adjustingRadius = null,Object? previewRadius = null,Object? previewPoint = freezed,Object? selectedGeofence = freezed,Object? editingGeofence = freezed,Object? selectedFrequentPlace = freezed,Object? selectedHistoryPosition = freezed,Object? isFollowing = null,Object? actionsExpanded = null,Object? frequencyExpanded = null,Object? mapZoom = null,}) {
return _then(_LocationMapViewState(
return _then(_LocationMapState(
showGeofences: null == showGeofences ? _self.showGeofences : showGeofences // ignore: cast_nullable_to_non_nullable
as bool,showFrequentPlaces: null == showFrequentPlaces ? _self.showFrequentPlaces : showFrequentPlaces // ignore: cast_nullable_to_non_nullable
as bool,placingMode: null == placingMode ? _self.placingMode : placingMode // ignore: cast_nullable_to_non_nullable
@@ -352,7 +352,7 @@ as double,
));
}
/// Create a copy of LocationMapViewState
/// Create a copy of LocationMapState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
@@ -364,7 +364,7 @@ $GeofenceEntityCopyWith<$Res>? get selectedGeofence {
return $GeofenceEntityCopyWith<$Res>(_self.selectedGeofence!, (value) {
return _then(_self.copyWith(selectedGeofence: value));
});
}/// Create a copy of LocationMapViewState
}/// Create a copy of LocationMapState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
@@ -376,7 +376,7 @@ $GeofenceEntityCopyWith<$Res>? get editingGeofence {
return $GeofenceEntityCopyWith<$Res>(_self.editingGeofence!, (value) {
return _then(_self.copyWith(editingGeofence: value));
});
}/// Create a copy of LocationMapViewState
}/// Create a copy of LocationMapState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
@@ -388,7 +388,7 @@ $FrequentPlaceEntityCopyWith<$Res>? get selectedFrequentPlace {
return $FrequentPlaceEntityCopyWith<$Res>(_self.selectedFrequentPlace!, (value) {
return _then(_self.copyWith(selectedFrequentPlace: value));
});
}/// Create a copy of LocationMapViewState
}/// Create a copy of LocationMapState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')

View File

@@ -0,0 +1,65 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:legacy_device_state/legacy_device_state.dart';
import 'package:location/src/core/domain/entities/frequent_place_entity.dart';
import 'package:location/src/core/domain/entities/geofence_entity.dart';
import 'package:sf_localizations/sf_localizations.dart';
part 'location_state.freezed.dart';
enum LocationSuccessEvent {
geofenceCreated,
geofenceUpdated,
geofenceDeleted,
frequentPlaceCreated,
frequentPlaceUpdated,
frequentPlaceDeleted,
}
enum LocationErrorEvent {
geofenceCreate,
geofenceUpdate,
geofenceDelete,
frequentPlaceCreate,
frequentPlaceUpdate,
frequentPlaceDelete,
positionHistory,
locationFrequency,
}
@freezed
abstract class LocationState with _$LocationState {
const factory LocationState({
@Default([]) List<GeofenceEntity> geofences,
@Default([]) List<FrequentPlaceEntity> frequentPlaces,
@Default([]) List<PositionEntity> positionHistory,
@Default(false) bool isLoadingHistory,
@Default(false) bool isSubmitting,
@Default(false) bool showRouteTrail,
LocationErrorEvent? errorEvent,
LocationSuccessEvent? successEvent,
}) = _LocationState;
}
extension LocationStateDisplay on LocationState {
String? get displayErrorKey => switch (errorEvent) {
null => null,
LocationErrorEvent.geofenceCreate => I18n.errorGeofenceCreate,
LocationErrorEvent.geofenceUpdate => I18n.errorGeofenceUpdate,
LocationErrorEvent.geofenceDelete => I18n.errorGeofenceDelete,
LocationErrorEvent.frequentPlaceCreate => I18n.errorFrequentPlaceCreate,
LocationErrorEvent.frequentPlaceUpdate => I18n.errorFrequentPlaceUpdate,
LocationErrorEvent.frequentPlaceDelete => I18n.errorFrequentPlaceDelete,
LocationErrorEvent.positionHistory => I18n.errorPositionHistory,
LocationErrorEvent.locationFrequency => I18n.errorLocationFrequency,
};
String? get displaySuccessKey => switch (successEvent) {
null => null,
LocationSuccessEvent.geofenceCreated => I18n.geofenceCreated,
LocationSuccessEvent.geofenceUpdated => I18n.geofenceUpdated,
LocationSuccessEvent.geofenceDeleted => I18n.geofenceDeleted,
LocationSuccessEvent.frequentPlaceCreated => I18n.frequentPlaceCreated,
LocationSuccessEvent.frequentPlaceUpdated => I18n.frequentPlaceUpdated,
LocationSuccessEvent.frequentPlaceDeleted => I18n.frequentPlaceDeleted,
};
}

View File

@@ -3,7 +3,7 @@
// ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
part of 'location_view_state.dart';
part of 'location_state.dart';
// **************************************************************************
// FreezedGenerator
@@ -12,40 +12,40 @@ part of 'location_view_state.dart';
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$LocationViewState {
mixin _$LocationState {
List<GeofenceEntity> get geofences; List<FrequentPlaceEntity> get frequentPlaces; List<PositionEntity> get positionHistory; bool get isLoadingHistory; bool get isSubmitting; bool get showRouteTrail; LocationErrorEvent? get errorEvent; LocationSuccessEvent? get successMessage;
/// Create a copy of LocationViewState
List<GeofenceEntity> get geofences; List<FrequentPlaceEntity> get frequentPlaces; List<PositionEntity> get positionHistory; bool get isLoadingHistory; bool get isSubmitting; bool get showRouteTrail; LocationErrorEvent? get errorEvent; LocationSuccessEvent? get successEvent;
/// Create a copy of LocationState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$LocationViewStateCopyWith<LocationViewState> get copyWith => _$LocationViewStateCopyWithImpl<LocationViewState>(this as LocationViewState, _$identity);
$LocationStateCopyWith<LocationState> get copyWith => _$LocationStateCopyWithImpl<LocationState>(this as LocationState, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is LocationViewState&&const DeepCollectionEquality().equals(other.geofences, geofences)&&const DeepCollectionEquality().equals(other.frequentPlaces, frequentPlaces)&&const DeepCollectionEquality().equals(other.positionHistory, positionHistory)&&(identical(other.isLoadingHistory, isLoadingHistory) || other.isLoadingHistory == isLoadingHistory)&&(identical(other.isSubmitting, isSubmitting) || other.isSubmitting == isSubmitting)&&(identical(other.showRouteTrail, showRouteTrail) || other.showRouteTrail == showRouteTrail)&&(identical(other.errorEvent, errorEvent) || other.errorEvent == errorEvent)&&(identical(other.successMessage, successMessage) || other.successMessage == successMessage));
return identical(this, other) || (other.runtimeType == runtimeType&&other is LocationState&&const DeepCollectionEquality().equals(other.geofences, geofences)&&const DeepCollectionEquality().equals(other.frequentPlaces, frequentPlaces)&&const DeepCollectionEquality().equals(other.positionHistory, positionHistory)&&(identical(other.isLoadingHistory, isLoadingHistory) || other.isLoadingHistory == isLoadingHistory)&&(identical(other.isSubmitting, isSubmitting) || other.isSubmitting == isSubmitting)&&(identical(other.showRouteTrail, showRouteTrail) || other.showRouteTrail == showRouteTrail)&&(identical(other.errorEvent, errorEvent) || other.errorEvent == errorEvent)&&(identical(other.successEvent, successEvent) || other.successEvent == successEvent));
}
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(geofences),const DeepCollectionEquality().hash(frequentPlaces),const DeepCollectionEquality().hash(positionHistory),isLoadingHistory,isSubmitting,showRouteTrail,errorEvent,successMessage);
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(geofences),const DeepCollectionEquality().hash(frequentPlaces),const DeepCollectionEquality().hash(positionHistory),isLoadingHistory,isSubmitting,showRouteTrail,errorEvent,successEvent);
@override
String toString() {
return 'LocationViewState(geofences: $geofences, frequentPlaces: $frequentPlaces, positionHistory: $positionHistory, isLoadingHistory: $isLoadingHistory, isSubmitting: $isSubmitting, showRouteTrail: $showRouteTrail, errorEvent: $errorEvent, successMessage: $successMessage)';
return 'LocationState(geofences: $geofences, frequentPlaces: $frequentPlaces, positionHistory: $positionHistory, isLoadingHistory: $isLoadingHistory, isSubmitting: $isSubmitting, showRouteTrail: $showRouteTrail, errorEvent: $errorEvent, successEvent: $successEvent)';
}
}
/// @nodoc
abstract mixin class $LocationViewStateCopyWith<$Res> {
factory $LocationViewStateCopyWith(LocationViewState value, $Res Function(LocationViewState) _then) = _$LocationViewStateCopyWithImpl;
abstract mixin class $LocationStateCopyWith<$Res> {
factory $LocationStateCopyWith(LocationState value, $Res Function(LocationState) _then) = _$LocationStateCopyWithImpl;
@useResult
$Res call({
List<GeofenceEntity> geofences, List<FrequentPlaceEntity> frequentPlaces, List<PositionEntity> positionHistory, bool isLoadingHistory, bool isSubmitting, bool showRouteTrail, LocationErrorEvent? errorEvent, LocationSuccessEvent? successMessage
List<GeofenceEntity> geofences, List<FrequentPlaceEntity> frequentPlaces, List<PositionEntity> positionHistory, bool isLoadingHistory, bool isSubmitting, bool showRouteTrail, LocationErrorEvent? errorEvent, LocationSuccessEvent? successEvent
});
@@ -53,16 +53,16 @@ $Res call({
}
/// @nodoc
class _$LocationViewStateCopyWithImpl<$Res>
implements $LocationViewStateCopyWith<$Res> {
_$LocationViewStateCopyWithImpl(this._self, this._then);
class _$LocationStateCopyWithImpl<$Res>
implements $LocationStateCopyWith<$Res> {
_$LocationStateCopyWithImpl(this._self, this._then);
final LocationViewState _self;
final $Res Function(LocationViewState) _then;
final LocationState _self;
final $Res Function(LocationState) _then;
/// Create a copy of LocationViewState
/// Create a copy of LocationState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? geofences = null,Object? frequentPlaces = null,Object? positionHistory = null,Object? isLoadingHistory = null,Object? isSubmitting = null,Object? showRouteTrail = null,Object? errorEvent = freezed,Object? successMessage = freezed,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? geofences = null,Object? frequentPlaces = null,Object? positionHistory = null,Object? isLoadingHistory = null,Object? isSubmitting = null,Object? showRouteTrail = null,Object? errorEvent = freezed,Object? successEvent = freezed,}) {
return _then(_self.copyWith(
geofences: null == geofences ? _self.geofences : geofences // ignore: cast_nullable_to_non_nullable
as List<GeofenceEntity>,frequentPlaces: null == frequentPlaces ? _self.frequentPlaces : frequentPlaces // ignore: cast_nullable_to_non_nullable
@@ -71,7 +71,7 @@ as List<PositionEntity>,isLoadingHistory: null == isLoadingHistory ? _self.isLoa
as bool,isSubmitting: null == isSubmitting ? _self.isSubmitting : isSubmitting // ignore: cast_nullable_to_non_nullable
as bool,showRouteTrail: null == showRouteTrail ? _self.showRouteTrail : showRouteTrail // ignore: cast_nullable_to_non_nullable
as bool,errorEvent: freezed == errorEvent ? _self.errorEvent : errorEvent // ignore: cast_nullable_to_non_nullable
as LocationErrorEvent?,successMessage: freezed == successMessage ? _self.successMessage : successMessage // ignore: cast_nullable_to_non_nullable
as LocationErrorEvent?,successEvent: freezed == successEvent ? _self.successEvent : successEvent // ignore: cast_nullable_to_non_nullable
as LocationSuccessEvent?,
));
}
@@ -79,8 +79,8 @@ as LocationSuccessEvent?,
}
/// Adds pattern-matching-related methods to [LocationViewState].
extension LocationViewStatePatterns on LocationViewState {
/// Adds pattern-matching-related methods to [LocationState].
extension LocationStatePatterns on LocationState {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
@@ -93,10 +93,10 @@ extension LocationViewStatePatterns on LocationViewState {
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _LocationViewState value)? $default,{required TResult orElse(),}){
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _LocationState value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _LocationViewState() when $default != null:
case _LocationState() when $default != null:
return $default(_that);case _:
return orElse();
@@ -115,10 +115,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _LocationViewState value) $default,){
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _LocationState value) $default,){
final _that = this;
switch (_that) {
case _LocationViewState():
case _LocationState():
return $default(_that);case _:
throw StateError('Unexpected subclass');
@@ -136,10 +136,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _LocationViewState value)? $default,){
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _LocationState value)? $default,){
final _that = this;
switch (_that) {
case _LocationViewState() when $default != null:
case _LocationState() when $default != null:
return $default(_that);case _:
return null;
@@ -157,10 +157,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( List<GeofenceEntity> geofences, List<FrequentPlaceEntity> frequentPlaces, List<PositionEntity> positionHistory, bool isLoadingHistory, bool isSubmitting, bool showRouteTrail, LocationErrorEvent? errorEvent, LocationSuccessEvent? successMessage)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( List<GeofenceEntity> geofences, List<FrequentPlaceEntity> frequentPlaces, List<PositionEntity> positionHistory, bool isLoadingHistory, bool isSubmitting, bool showRouteTrail, LocationErrorEvent? errorEvent, LocationSuccessEvent? successEvent)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _LocationViewState() when $default != null:
return $default(_that.geofences,_that.frequentPlaces,_that.positionHistory,_that.isLoadingHistory,_that.isSubmitting,_that.showRouteTrail,_that.errorEvent,_that.successMessage);case _:
case _LocationState() when $default != null:
return $default(_that.geofences,_that.frequentPlaces,_that.positionHistory,_that.isLoadingHistory,_that.isSubmitting,_that.showRouteTrail,_that.errorEvent,_that.successEvent);case _:
return orElse();
}
@@ -178,10 +178,10 @@ return $default(_that.geofences,_that.frequentPlaces,_that.positionHistory,_that
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( List<GeofenceEntity> geofences, List<FrequentPlaceEntity> frequentPlaces, List<PositionEntity> positionHistory, bool isLoadingHistory, bool isSubmitting, bool showRouteTrail, LocationErrorEvent? errorEvent, LocationSuccessEvent? successMessage) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( List<GeofenceEntity> geofences, List<FrequentPlaceEntity> frequentPlaces, List<PositionEntity> positionHistory, bool isLoadingHistory, bool isSubmitting, bool showRouteTrail, LocationErrorEvent? errorEvent, LocationSuccessEvent? successEvent) $default,) {final _that = this;
switch (_that) {
case _LocationViewState():
return $default(_that.geofences,_that.frequentPlaces,_that.positionHistory,_that.isLoadingHistory,_that.isSubmitting,_that.showRouteTrail,_that.errorEvent,_that.successMessage);case _:
case _LocationState():
return $default(_that.geofences,_that.frequentPlaces,_that.positionHistory,_that.isLoadingHistory,_that.isSubmitting,_that.showRouteTrail,_that.errorEvent,_that.successEvent);case _:
throw StateError('Unexpected subclass');
}
@@ -198,10 +198,10 @@ return $default(_that.geofences,_that.frequentPlaces,_that.positionHistory,_that
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( List<GeofenceEntity> geofences, List<FrequentPlaceEntity> frequentPlaces, List<PositionEntity> positionHistory, bool isLoadingHistory, bool isSubmitting, bool showRouteTrail, LocationErrorEvent? errorEvent, LocationSuccessEvent? successMessage)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( List<GeofenceEntity> geofences, List<FrequentPlaceEntity> frequentPlaces, List<PositionEntity> positionHistory, bool isLoadingHistory, bool isSubmitting, bool showRouteTrail, LocationErrorEvent? errorEvent, LocationSuccessEvent? successEvent)? $default,) {final _that = this;
switch (_that) {
case _LocationViewState() when $default != null:
return $default(_that.geofences,_that.frequentPlaces,_that.positionHistory,_that.isLoadingHistory,_that.isSubmitting,_that.showRouteTrail,_that.errorEvent,_that.successMessage);case _:
case _LocationState() when $default != null:
return $default(_that.geofences,_that.frequentPlaces,_that.positionHistory,_that.isLoadingHistory,_that.isSubmitting,_that.showRouteTrail,_that.errorEvent,_that.successEvent);case _:
return null;
}
@@ -212,8 +212,8 @@ return $default(_that.geofences,_that.frequentPlaces,_that.positionHistory,_that
/// @nodoc
class _LocationViewState implements LocationViewState {
const _LocationViewState({final List<GeofenceEntity> geofences = const [], final List<FrequentPlaceEntity> frequentPlaces = const [], final List<PositionEntity> positionHistory = const [], this.isLoadingHistory = false, this.isSubmitting = false, this.showRouteTrail = false, this.errorEvent, this.successMessage}): _geofences = geofences,_frequentPlaces = frequentPlaces,_positionHistory = positionHistory;
class _LocationState implements LocationState {
const _LocationState({final List<GeofenceEntity> geofences = const [], final List<FrequentPlaceEntity> frequentPlaces = const [], final List<PositionEntity> positionHistory = const [], this.isLoadingHistory = false, this.isSubmitting = false, this.showRouteTrail = false, this.errorEvent, this.successEvent}): _geofences = geofences,_frequentPlaces = frequentPlaces,_positionHistory = positionHistory;
final List<GeofenceEntity> _geofences;
@@ -241,39 +241,39 @@ class _LocationViewState implements LocationViewState {
@override@JsonKey() final bool isSubmitting;
@override@JsonKey() final bool showRouteTrail;
@override final LocationErrorEvent? errorEvent;
@override final LocationSuccessEvent? successMessage;
@override final LocationSuccessEvent? successEvent;
/// Create a copy of LocationViewState
/// Create a copy of LocationState
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$LocationViewStateCopyWith<_LocationViewState> get copyWith => __$LocationViewStateCopyWithImpl<_LocationViewState>(this, _$identity);
_$LocationStateCopyWith<_LocationState> get copyWith => __$LocationStateCopyWithImpl<_LocationState>(this, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _LocationViewState&&const DeepCollectionEquality().equals(other._geofences, _geofences)&&const DeepCollectionEquality().equals(other._frequentPlaces, _frequentPlaces)&&const DeepCollectionEquality().equals(other._positionHistory, _positionHistory)&&(identical(other.isLoadingHistory, isLoadingHistory) || other.isLoadingHistory == isLoadingHistory)&&(identical(other.isSubmitting, isSubmitting) || other.isSubmitting == isSubmitting)&&(identical(other.showRouteTrail, showRouteTrail) || other.showRouteTrail == showRouteTrail)&&(identical(other.errorEvent, errorEvent) || other.errorEvent == errorEvent)&&(identical(other.successMessage, successMessage) || other.successMessage == successMessage));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _LocationState&&const DeepCollectionEquality().equals(other._geofences, _geofences)&&const DeepCollectionEquality().equals(other._frequentPlaces, _frequentPlaces)&&const DeepCollectionEquality().equals(other._positionHistory, _positionHistory)&&(identical(other.isLoadingHistory, isLoadingHistory) || other.isLoadingHistory == isLoadingHistory)&&(identical(other.isSubmitting, isSubmitting) || other.isSubmitting == isSubmitting)&&(identical(other.showRouteTrail, showRouteTrail) || other.showRouteTrail == showRouteTrail)&&(identical(other.errorEvent, errorEvent) || other.errorEvent == errorEvent)&&(identical(other.successEvent, successEvent) || other.successEvent == successEvent));
}
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_geofences),const DeepCollectionEquality().hash(_frequentPlaces),const DeepCollectionEquality().hash(_positionHistory),isLoadingHistory,isSubmitting,showRouteTrail,errorEvent,successMessage);
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_geofences),const DeepCollectionEquality().hash(_frequentPlaces),const DeepCollectionEquality().hash(_positionHistory),isLoadingHistory,isSubmitting,showRouteTrail,errorEvent,successEvent);
@override
String toString() {
return 'LocationViewState(geofences: $geofences, frequentPlaces: $frequentPlaces, positionHistory: $positionHistory, isLoadingHistory: $isLoadingHistory, isSubmitting: $isSubmitting, showRouteTrail: $showRouteTrail, errorEvent: $errorEvent, successMessage: $successMessage)';
return 'LocationState(geofences: $geofences, frequentPlaces: $frequentPlaces, positionHistory: $positionHistory, isLoadingHistory: $isLoadingHistory, isSubmitting: $isSubmitting, showRouteTrail: $showRouteTrail, errorEvent: $errorEvent, successEvent: $successEvent)';
}
}
/// @nodoc
abstract mixin class _$LocationViewStateCopyWith<$Res> implements $LocationViewStateCopyWith<$Res> {
factory _$LocationViewStateCopyWith(_LocationViewState value, $Res Function(_LocationViewState) _then) = __$LocationViewStateCopyWithImpl;
abstract mixin class _$LocationStateCopyWith<$Res> implements $LocationStateCopyWith<$Res> {
factory _$LocationStateCopyWith(_LocationState value, $Res Function(_LocationState) _then) = __$LocationStateCopyWithImpl;
@override @useResult
$Res call({
List<GeofenceEntity> geofences, List<FrequentPlaceEntity> frequentPlaces, List<PositionEntity> positionHistory, bool isLoadingHistory, bool isSubmitting, bool showRouteTrail, LocationErrorEvent? errorEvent, LocationSuccessEvent? successMessage
List<GeofenceEntity> geofences, List<FrequentPlaceEntity> frequentPlaces, List<PositionEntity> positionHistory, bool isLoadingHistory, bool isSubmitting, bool showRouteTrail, LocationErrorEvent? errorEvent, LocationSuccessEvent? successEvent
});
@@ -281,17 +281,17 @@ $Res call({
}
/// @nodoc
class __$LocationViewStateCopyWithImpl<$Res>
implements _$LocationViewStateCopyWith<$Res> {
__$LocationViewStateCopyWithImpl(this._self, this._then);
class __$LocationStateCopyWithImpl<$Res>
implements _$LocationStateCopyWith<$Res> {
__$LocationStateCopyWithImpl(this._self, this._then);
final _LocationViewState _self;
final $Res Function(_LocationViewState) _then;
final _LocationState _self;
final $Res Function(_LocationState) _then;
/// Create a copy of LocationViewState
/// Create a copy of LocationState
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? geofences = null,Object? frequentPlaces = null,Object? positionHistory = null,Object? isLoadingHistory = null,Object? isSubmitting = null,Object? showRouteTrail = null,Object? errorEvent = freezed,Object? successMessage = freezed,}) {
return _then(_LocationViewState(
@override @pragma('vm:prefer-inline') $Res call({Object? geofences = null,Object? frequentPlaces = null,Object? positionHistory = null,Object? isLoadingHistory = null,Object? isSubmitting = null,Object? showRouteTrail = null,Object? errorEvent = freezed,Object? successEvent = freezed,}) {
return _then(_LocationState(
geofences: null == geofences ? _self._geofences : geofences // ignore: cast_nullable_to_non_nullable
as List<GeofenceEntity>,frequentPlaces: null == frequentPlaces ? _self._frequentPlaces : frequentPlaces // ignore: cast_nullable_to_non_nullable
as List<FrequentPlaceEntity>,positionHistory: null == positionHistory ? _self._positionHistory : positionHistory // ignore: cast_nullable_to_non_nullable
@@ -299,7 +299,7 @@ as List<PositionEntity>,isLoadingHistory: null == isLoadingHistory ? _self.isLoa
as bool,isSubmitting: null == isSubmitting ? _self.isSubmitting : isSubmitting // ignore: cast_nullable_to_non_nullable
as bool,showRouteTrail: null == showRouteTrail ? _self.showRouteTrail : showRouteTrail // ignore: cast_nullable_to_non_nullable
as bool,errorEvent: freezed == errorEvent ? _self.errorEvent : errorEvent // ignore: cast_nullable_to_non_nullable
as LocationErrorEvent?,successMessage: freezed == successMessage ? _self.successMessage : successMessage // ignore: cast_nullable_to_non_nullable
as LocationErrorEvent?,successEvent: freezed == successEvent ? _self.successEvent : successEvent // ignore: cast_nullable_to_non_nullable
as LocationSuccessEvent?,
));
}

View File

@@ -0,0 +1,11 @@
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'map_style_selector_controller.g.dart';
@riverpod
class MapStyleSelectorExpanded extends _$MapStyleSelectorExpanded {
@override
bool build() => false;
void set(bool value) => state = value;
}

View File

@@ -0,0 +1,64 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'map_style_selector_controller.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint, type=warning
@ProviderFor(MapStyleSelectorExpanded)
const mapStyleSelectorExpandedProvider = MapStyleSelectorExpandedProvider._();
final class MapStyleSelectorExpandedProvider
extends $NotifierProvider<MapStyleSelectorExpanded, bool> {
const MapStyleSelectorExpandedProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'mapStyleSelectorExpandedProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$mapStyleSelectorExpandedHash();
@$internal
@override
MapStyleSelectorExpanded create() => MapStyleSelectorExpanded();
/// {@macro riverpod.override_with_value}
Override overrideWithValue(bool value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<bool>(value),
);
}
}
String _$mapStyleSelectorExpandedHash() =>
r'319f7a0ce2dc9bce1025bb52a0ead0a457eaf455';
abstract class _$MapStyleSelectorExpanded extends $Notifier<bool> {
bool build();
@$mustCallSuper
@override
void runBuild() {
final created = build();
final ref = this.ref as $Ref<bool, bool>;
final element =
ref.element
as $ClassProviderElement<
AnyNotifier<bool, bool>,
bool,
Object?,
Object?
>;
element.handleValue(ref, created);
}
}

View File

@@ -1,40 +0,0 @@
import 'package:legacy_device_state/legacy_device_state.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:location/src/core/domain/entities/geofence_entity.dart';
import 'package:location/src/core/domain/entities/frequent_place_entity.dart';
part 'location_view_state.freezed.dart';
enum LocationSuccessEvent {
geofenceCreated,
geofenceUpdated,
geofenceDeleted,
frequentPlaceCreated,
frequentPlaceUpdated,
frequentPlaceDeleted,
}
enum LocationErrorEvent {
geofenceCreate,
geofenceUpdate,
geofenceDelete,
frequentPlaceCreate,
frequentPlaceUpdate,
frequentPlaceDelete,
positionHistory,
locationFrequency,
}
@freezed
abstract class LocationViewState with _$LocationViewState {
const factory LocationViewState({
@Default([]) List<GeofenceEntity> geofences,
@Default([]) List<FrequentPlaceEntity> frequentPlaces,
@Default([]) List<PositionEntity> positionHistory,
@Default(false) bool isLoadingHistory,
@Default(false) bool isSubmitting,
@Default(false) bool showRouteTrail,
LocationErrorEvent? errorEvent,
LocationSuccessEvent? successMessage,
}) = _LocationViewState;
}

View File

@@ -1,287 +0,0 @@
import 'package:legacy_theme/legacy_theme.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:latlong2/latlong.dart';
import 'package:legacy_device_state/legacy_device_state.dart';
import 'package:location/src/core/domain/entities/frequent_place_entity.dart';
import 'package:sf_localizations/sf_localizations.dart';
import 'package:utils/utils.dart';
import '../state/location_view_model.dart';
import 'location_input_decoration.dart';
Future<void> showCreateFrequentPlaceSheet(
BuildContext context, {
required LatLng point,
}) {
return showModalBottomSheet<void>(
context: context,
isScrollControlled: true,
backgroundColor: Colors.transparent,
builder: (_) => _FrequentPlaceSheet(point: point),
);
}
Future<void> showEditFrequentPlaceSheet(
BuildContext context, {
required FrequentPlaceEntity frequentPlace,
}) {
return showModalBottomSheet<void>(
context: context,
isScrollControlled: true,
backgroundColor: Colors.transparent,
builder: (_) => _FrequentPlaceSheet(
point: LatLng(frequentPlace.lat, frequentPlace.lng),
editingPlace: frequentPlace,
),
);
}
class _FrequentPlaceSheet extends ConsumerStatefulWidget {
final LatLng point;
final FrequentPlaceEntity? editingPlace;
const _FrequentPlaceSheet({required this.point, this.editingPlace});
@override
ConsumerState<_FrequentPlaceSheet> createState() =>
_FrequentPlaceSheetState();
}
class _FrequentPlaceSheetState extends ConsumerState<_FrequentPlaceSheet> {
final _nameController = TextEditingController();
late List<WifiInfoEntity> _wifiList;
bool get _isEditing => widget.editingPlace != null;
@override
void initState() {
super.initState();
if (_isEditing) {
_nameController.text = widget.editingPlace!.name;
_wifiList = List.of(widget.editingPlace!.wifiList);
} else {
_wifiList = [];
}
}
@override
void dispose() {
_nameController.dispose();
super.dispose();
}
bool get _canSave => _nameController.text.trim().isNotEmpty;
Future<void> _submit() async {
if (!_canSave) return;
if (!await guardDeviceCommand(context, ref)) return;
final vm = ref.read(locationViewModelProvider.notifier);
final bool success;
if (_isEditing) {
success = await vm.updateFrequentPlace(
id: widget.editingPlace!.id,
name: _nameController.text.trim(),
lat: widget.point.latitude,
lng: widget.point.longitude,
wifiList: _wifiList,
);
} else {
success = await vm.createFrequentPlace(
name: _nameController.text.trim(),
lat: widget.point.latitude,
lng: widget.point.longitude,
wifiList: _wifiList,
);
}
if (success && mounted) {
Navigator.pop(context);
}
}
void _addWifi() {
setState(() {
_wifiList.add(WifiInfoEntity(ssid: '', bssid: '', signal: ''));
});
}
void _removeWifi(int index) {
setState(() => _wifiList.removeAt(index));
}
void _updateWifi(int index, WifiInfoEntity updated) {
setState(() => _wifiList[index] = updated);
}
@override
Widget build(BuildContext context) {
final primaryColor = context.sfColors.legacyPrimary;
final isSubmitting = ref.watch(
locationViewModelProvider.select((s) => s.value?.isSubmitting ?? false),
);
final errorEvent = ref.watch(
locationViewModelProvider.select((s) => s.value?.errorEvent),
);
return DraggableScrollableSheet(
initialChildSize: 0.25,
minChildSize: 0.15,
maxChildSize: 0.7,
builder: (context, scrollController) {
return Container(
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
),
child: ListView(
controller: scrollController,
padding: EdgeInsets.symmetric(
horizontal: SizeUtils.getByScreen(small: 22, big: 24),
vertical: SizeUtils.getByScreen(small: 12, big: 14),
),
children: [
Center(
child: Container(
width: 40,
height: 4,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.outline,
borderRadius: BorderRadius.circular(2),
),
),
),
SizedBox(height: SizeUtils.getByScreen(small: 10, big: 12)),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text(
_isEditing
? context.translate(I18n.locationEditFrequentPlace)
: context.translate(I18n.locationNewFrequentPlace),
style: TextStyle(
fontSize: SizeUtils.getByScreen(small: 18, big: 19),
fontWeight: FontWeight.w600,
color: primaryColor,
),
),
),
TextButton(
onPressed: _canSave && !isSubmitting ? _submit : null,
child: isSubmitting
? SizedBox(
width: SizeUtils.getByScreen(small: 20, big: 22),
height: SizeUtils.getByScreen(small: 20, big: 22),
child: CircularProgressIndicator(
strokeWidth: 2,
color: primaryColor,
),
)
: Text(
_isEditing
? context.translate(I18n.locationSave)
: context.translate(I18n.locationCreate),
style: TextStyle(
color: _canSave ? primaryColor : Colors.grey,
fontWeight: FontWeight.w600,
fontSize: SizeUtils.getByScreen(
small: 16,
big: 17,
),
),
),
),
],
),
const SizedBox(height: 8),
Text(
context.translate(I18n.name),
style: TextStyle(
fontSize: SizeUtils.getByScreen(small: 15, big: 16),
fontWeight: FontWeight.w500,
),
),
const SizedBox(height: 8),
TextField(
controller: _nameController,
onChanged: (_) => setState(() {}),
decoration: locationInputDecoration(
hintText: context.translate(I18n.locationHintFrequentPlace),
primaryColor: primaryColor,
),
),
if (_isEditing) ...[
SizedBox(height: SizeUtils.getByScreen(small: 14, big: 16)),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
context.translate(I18n.locationWifiNetworksOptional),
style: TextStyle(
fontSize: SizeUtils.getByScreen(small: 15, big: 16),
fontWeight: FontWeight.w500,
),
),
GestureDetector(
onTap: _addWifi,
child: Icon(
Icons.add_circle_outline,
color: primaryColor,
size: 24,
),
),
],
),
const SizedBox(height: 8),
..._wifiList.asMap().entries.map((entry) {
final i = entry.key;
final wifi = entry.value;
return Padding(
padding: const EdgeInsets.only(bottom: 8),
child: Row(
children: [
Expanded(
child: TextFormField(
initialValue: wifi.ssid,
onChanged: (v) =>
_updateWifi(i, wifi.copyWith(ssid: v)),
decoration: locationInputDecoration(
hintText: 'SSID',
primaryColor: primaryColor,
),
style: const TextStyle(fontSize: 13),
),
),
SizedBox(width: 8),
GestureDetector(
onTap: () => _removeWifi(i),
child: Icon(
Icons.remove_circle_outline,
color: Theme.of(context).colorScheme.onSurfaceVariant,
size: 22,
),
),
],
),
);
}),
],
if (errorEvent != null)
Padding(
padding: const EdgeInsets.only(top: 8),
child: Text(
context.translate(I18n.errorGeneric),
style: TextStyle(color: Theme.of(context).colorScheme.error, fontSize: 13),
),
),
SizedBox(height: SizeUtils.getByScreen(small: 8, big: 10)),
],
),
);
},
);
}
}

View File

@@ -1,267 +0,0 @@
import 'package:legacy_theme/legacy_theme.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:latlong2/latlong.dart';
import 'package:legacy_device_state/legacy_device_state.dart';
import 'package:location/src/core/domain/entities/geofence_entity.dart';
import 'package:sf_localizations/sf_localizations.dart';
import 'package:utils/utils.dart';
import '../state/location_view_model.dart';
import 'location_input_decoration.dart';
Future<void> showCreateGeofenceSheet(
BuildContext context, {
required LatLng point,
required ValueNotifier<double> previewRadius,
}) {
return showModalBottomSheet<void>(
context: context,
isScrollControlled: true,
backgroundColor: Colors.transparent,
builder: (_) => _GeofenceSheet(point: point, previewRadius: previewRadius),
);
}
Future<void> showEditGeofenceSheet(
BuildContext context, {
required GeofenceEntity geofence,
required ValueNotifier<double> previewRadius,
}) {
previewRadius.value = geofence.radius;
return showModalBottomSheet<void>(
context: context,
isScrollControlled: true,
backgroundColor: Colors.transparent,
builder: (_) => _GeofenceSheet(
point: LatLng(geofence.latitude, geofence.longitude),
previewRadius: previewRadius,
editingGeofence: geofence,
),
);
}
class _GeofenceSheet extends ConsumerStatefulWidget {
final LatLng point;
final ValueNotifier<double> previewRadius;
final GeofenceEntity? editingGeofence;
const _GeofenceSheet({
required this.point,
required this.previewRadius,
this.editingGeofence,
});
@override
ConsumerState<_GeofenceSheet> createState() => _GeofenceSheetState();
}
class _GeofenceSheetState extends ConsumerState<_GeofenceSheet> {
final _nameController = TextEditingController();
final _descriptionController = TextEditingController();
late double _radius;
bool get _isEditing => widget.editingGeofence != null;
@override
void initState() {
super.initState();
if (_isEditing) {
_nameController.text = widget.editingGeofence!.name;
_descriptionController.text = widget.editingGeofence!.description ?? '';
_radius = widget.editingGeofence!.radius;
} else {
_radius = 200;
}
}
@override
void dispose() {
_nameController.dispose();
_descriptionController.dispose();
super.dispose();
}
bool get _canSave => _nameController.text.trim().isNotEmpty;
void _onRadiusChanged(double value) {
setState(() => _radius = value);
widget.previewRadius.value = value;
}
Future<void> _submit() async {
if (!_canSave) return;
if (!await guardDeviceCommand(context, ref)) return;
final vm = ref.read(locationViewModelProvider.notifier);
final description = _descriptionController.text.trim();
final bool success;
if (_isEditing) {
success = await vm.updateGeofence(
id: widget.editingGeofence!.id,
name: _nameController.text.trim(),
description: description.isNotEmpty ? description : null,
latitude: widget.point.latitude,
longitude: widget.point.longitude,
radius: _radius,
);
} else {
success = await vm.createGeofence(
name: _nameController.text.trim(),
description: description.isNotEmpty ? description : null,
latitude: widget.point.latitude,
longitude: widget.point.longitude,
radius: _radius,
);
}
if (success && mounted) {
Navigator.pop(context);
}
}
@override
Widget build(BuildContext context) {
final primaryColor = context.sfColors.legacyPrimary;
final isSubmitting = ref.watch(
locationViewModelProvider.select((s) => s.value?.isSubmitting ?? false),
);
final errorEvent = ref.watch(
locationViewModelProvider.select((s) => s.value?.errorEvent),
);
return DraggableScrollableSheet(
initialChildSize: 0.35,
minChildSize: 0.15,
maxChildSize: 0.7,
builder: (context, scrollController) {
return Container(
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
),
child: ListView(
controller: scrollController,
padding: EdgeInsets.symmetric(
horizontal: SizeUtils.getByScreen(small: 22, big: 24),
vertical: SizeUtils.getByScreen(small: 12, big: 14),
),
children: [
Center(
child: Container(
width: 40,
height: 4,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.outline,
borderRadius: BorderRadius.circular(2),
),
),
),
SizedBox(height: SizeUtils.getByScreen(small: 10, big: 12)),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
_isEditing
? context.translate(I18n.locationEditGeofence)
: context.translate(I18n.locationNewGeofence),
style: TextStyle(
fontSize: SizeUtils.getByScreen(small: 18, big: 19),
fontWeight: FontWeight.w600,
color: primaryColor,
),
),
TextButton(
onPressed: _canSave && !isSubmitting ? _submit : null,
child: isSubmitting
? SizedBox(
width: SizeUtils.getByScreen(small: 20, big: 22),
height: SizeUtils.getByScreen(small: 20, big: 22),
child: CircularProgressIndicator(
strokeWidth: 2,
color: primaryColor,
),
)
: Text(
_isEditing
? context.translate(I18n.locationSave)
: context.translate(I18n.locationCreate),
style: TextStyle(
color: _canSave ? primaryColor : Colors.grey,
fontWeight: FontWeight.w600,
fontSize: SizeUtils.getByScreen(
small: 16,
big: 17,
),
),
),
),
],
),
const SizedBox(height: 8),
Text(
'${context.translate(I18n.locationRadius)}: ${context.translate(I18n.locationRadiusMeters, args: {'radius': '${_radius.round()}'})}',
style: TextStyle(
fontSize: SizeUtils.getByScreen(small: 15, big: 16),
fontWeight: FontWeight.w500,
),
),
Slider(
value: _radius,
min: 50,
max: 2000,
divisions: 39,
activeColor: primaryColor,
label: '${_radius.round()} m',
onChanged: _onRadiusChanged,
),
const SizedBox(height: 8),
Text(
context.translate(I18n.name),
style: TextStyle(
fontSize: SizeUtils.getByScreen(small: 15, big: 16),
fontWeight: FontWeight.w500,
),
),
const SizedBox(height: 8),
TextField(
controller: _nameController,
onChanged: (_) => setState(() {}),
decoration: locationInputDecoration(
hintText: context.translate(I18n.locationHintGeofence),
primaryColor: primaryColor,
),
),
SizedBox(height: SizeUtils.getByScreen(small: 14, big: 16)),
Text(
context.translate(I18n.locationHintDescription),
style: TextStyle(
fontSize: SizeUtils.getByScreen(small: 15, big: 16),
fontWeight: FontWeight.w500,
),
),
const SizedBox(height: 8),
TextField(
controller: _descriptionController,
decoration: locationInputDecoration(
hintText: context.translate(I18n.locationHintDescription),
primaryColor: primaryColor,
),
),
if (errorEvent != null)
Padding(
padding: const EdgeInsets.only(top: 8),
child: Text(
context.translate(I18n.errorGeneric),
style: TextStyle(color: Theme.of(context).colorScheme.error, fontSize: 13),
),
),
SizedBox(height: SizeUtils.getByScreen(small: 8, big: 10)),
],
),
);
},
);
}
}

View File

@@ -26,24 +26,27 @@ class DeviceBanner extends ConsumerStatefulWidget {
class _DeviceBannerState extends ConsumerState<DeviceBanner> {
late final PageController _pageController;
int _currentPage = 0;
int get _currentPage {
final idx = widget.devices.indexWhere((d) => d.id == widget.device.id);
return idx < 0 ? 0 : idx;
}
@override
void initState() {
super.initState();
_currentPage = widget.devices.indexWhere((d) => d.id == widget.device.id);
if (_currentPage < 0) _currentPage = 0;
_pageController = PageController(initialPage: _currentPage);
}
@override
void didUpdateWidget(DeviceBanner oldWidget) {
super.didUpdateWidget(oldWidget);
final newIndex = widget.devices.indexWhere((d) => d.id == widget.device.id);
if (newIndex >= 0 && newIndex != _currentPage) {
_currentPage = newIndex;
final page = _pageController.hasClients
? _pageController.page?.round() ?? _currentPage
: _currentPage;
if (page != _currentPage) {
_pageController.animateToPage(
newIndex,
_currentPage,
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
);
@@ -84,10 +87,8 @@ class _DeviceBannerState extends ConsumerState<DeviceBanner> {
child: PageView.builder(
controller: _pageController,
itemCount: widget.devices.length,
onPageChanged: (index) {
setState(() => _currentPage = index);
widget.onDeviceChanged(widget.devices[index]);
},
onPageChanged: (index) =>
widget.onDeviceChanged(widget.devices[index]),
itemBuilder: (context, index) {
final dev = widget.devices[index];
final pos = widget.positions

View File

@@ -3,8 +3,9 @@ import 'dart:async';
import 'package:legacy_device_state/legacy_device_state.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:location/src/core/domain/entities/geofence_entity.dart';
import 'package:location/src/core/domain/entities/frequent_place_entity.dart';
import 'package:location/src/core/domain/entities/geofence_entity.dart';
import 'package:location/src/features/location/presentation/providers/location_list_filter_controller.dart';
import 'package:sf_localizations/sf_localizations.dart';
import 'package:sf_tracking/sf_tracking.dart';
@@ -33,12 +34,10 @@ class LocationListSheet extends ConsumerStatefulWidget {
}
class _LocationListSheetState extends ConsumerState<LocationListSheet> {
String? _selectedType;
List<PositionEntity> get _filteredHistory {
if (_selectedType == null) return widget.positionHistory;
List<PositionEntity> _filterHistory(String? selectedType) {
if (selectedType == null) return widget.positionHistory;
return widget.positionHistory
.where((p) => p.type == _selectedType)
.where((p) => p.type == selectedType)
.toList();
}
@@ -48,7 +47,8 @@ class _LocationListSheetState extends ConsumerState<LocationListSheet> {
@override
Widget build(BuildContext context) {
final filtered = _filteredHistory;
final selectedType = ref.watch(locationListFilterProvider);
final filtered = _filterHistory(selectedType);
return DraggableScrollableSheet(
initialChildSize: 0.45,
@@ -125,7 +125,7 @@ class _LocationListSheetState extends ConsumerState<LocationListSheet> {
count: filtered.length,
),
if (_availableTypes.length > 1)
_buildTypeFilters(context),
_buildTypeFilters(context, selectedType),
...filtered.map(_buildHistoryTile),
const SizedBox(height: 16),
],
@@ -154,7 +154,7 @@ class _LocationListSheetState extends ConsumerState<LocationListSheet> {
);
}
Widget _buildTypeFilters(BuildContext context) {
Widget _buildTypeFilters(BuildContext context, String? selectedType) {
return Padding(
padding: const EdgeInsets.only(bottom: 10),
child: Wrap(
@@ -163,16 +163,25 @@ class _LocationListSheetState extends ConsumerState<LocationListSheet> {
_buildFilterChip(
label: context.translate(I18n.locationListAll),
value: null,
selectedType: selectedType,
),
for (final type in _availableTypes.toList()..sort())
_buildFilterChip(label: type, value: type),
_buildFilterChip(
label: type,
value: type,
selectedType: selectedType,
),
],
),
);
}
Widget _buildFilterChip({required String label, required String? value}) {
final isSelected = _selectedType == value;
Widget _buildFilterChip({
required String label,
required String? value,
required String? selectedType,
}) {
final isSelected = selectedType == value;
return GestureDetector(
onTap: () {
unawaited(
@@ -180,7 +189,7 @@ class _LocationListSheetState extends ConsumerState<LocationListSheet> {
.read(sfTrackingProvider)
.legacyLocationHistoryTypeFilterChanged(value ?? 'all'),
);
setState(() => _selectedType = value);
ref.read(locationListFilterProvider.notifier).select(value);
},
child: AnimatedContainer(
duration: const Duration(milliseconds: 200),

View File

@@ -1,7 +1,6 @@
import 'dart:async';
import 'package:share_plus/share_plus.dart';
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
@@ -10,9 +9,9 @@ import 'package:legacy_ui/legacy_ui.dart';
import 'package:legacy_device_state/legacy_device_state.dart';
import 'package:location/src/core/domain/entities/geofence_entity.dart';
import 'package:location/src/core/domain/entities/frequent_place_entity.dart';
import 'package:location/src/features/location/presentation/state/location_map_view_model.dart';
import 'package:location/src/features/location/presentation/state/location_map_view_state.dart';
import 'package:location/src/features/location/presentation/state/location_view_model.dart';
import 'package:location/src/features/location/presentation/providers/location_map_controller.dart';
import 'package:location/src/features/location/presentation/providers/location_map_state.dart';
import 'package:location/src/features/location/presentation/providers/location_controller.dart';
import 'package:sf_localizations/sf_localizations.dart';
import 'package:sf_shared/sf_shared.dart';
import 'package:sf_tracking/sf_tracking.dart';
@@ -75,8 +74,8 @@ class _LocationMapState extends ConsumerState<LocationMap>
AnimationController? _moveAnimation;
Timer? _followTimer;
LocationMapViewModel get _vm =>
ref.read(locationMapViewModelProvider.notifier);
LocationMapController get _vm =>
ref.read(locationMapControllerProvider.notifier);
Color get _primaryColor =>
context.sfColors.legacyPrimary;
@@ -123,7 +122,7 @@ class _LocationMapState extends ConsumerState<LocationMap>
} else if (widget.selectedPosition != null &&
widget.selectedPosition != oldWidget.selectedPosition) {
final firstFix = oldWidget.selectedPosition == null;
final isFollowing = ref.read(locationMapViewModelProvider).isFollowing;
final isFollowing = ref.read(locationMapControllerProvider).isFollowing;
if (firstFix || isFollowing) _centerOnDevice();
}
@@ -249,7 +248,7 @@ class _LocationMapState extends ConsumerState<LocationMap>
Future<void> _updateFrequency(int frequency) async {
if (!await guardDeviceCommand(context, ref)) return;
final success = await ref
.read(locationViewModelProvider.notifier)
.read(locationControllerProvider.notifier)
.updateLocationFrequency(frequency: frequency);
if (!mounted) return;
if (success) {
@@ -258,19 +257,10 @@ class _LocationMapState extends ConsumerState<LocationMap>
_followTimer = Timer.periodic(Duration(seconds: safeFrequency), (_) {
widget.onRefreshPosition();
});
showTopSnackbar(
await showSuccessDialog(
context,
message: context.translate(
I18n.locationFrequencyUpdated,
args: {'minutes': '${frequency ~/ 60}'},
),
type: MessageType.success,
);
} else {
showTopSnackbar(
context,
message: context.translate(I18n.errorLocationFrequency),
type: MessageType.error,
I18n.locationFrequencyUpdated,
args: {'minutes': '${frequency ~/ 60}'},
);
}
}
@@ -279,7 +269,7 @@ class _LocationMapState extends ConsumerState<LocationMap>
if (!await guardDeviceCommand(context, ref)) return;
if (!mounted) return;
final center = _mapController.camera.center;
final mapState = ref.read(locationMapViewModelProvider);
final mapState = ref.read(locationMapControllerProvider);
if (mapState.placingMode == PlacingMode.geofence) {
_vm.confirmGeofencePlacement(center);
@@ -291,7 +281,7 @@ class _LocationMapState extends ConsumerState<LocationMap>
title: context.translate(I18n.locationNewFrequentPlace),
hintText: context.translate(I18n.locationHintFrequentPlace),
onSubmit: (name, _) => ref
.read(locationViewModelProvider.notifier)
.read(locationControllerProvider.notifier)
.createFrequentPlace(
name: name,
lat: center.latitude,
@@ -304,7 +294,7 @@ class _LocationMapState extends ConsumerState<LocationMap>
Future<void> _confirmRadius() async {
if (!await guardDeviceCommand(context, ref)) return;
if (!mounted) return;
final mapState = ref.read(locationMapViewModelProvider);
final mapState = ref.read(locationMapControllerProvider);
final point = mapState.previewPoint!;
final radius = mapState.previewRadius;
final editing = mapState.editingGeofence;
@@ -326,7 +316,7 @@ class _LocationMapState extends ConsumerState<LocationMap>
onSubmit: (name, description) {
if (editing != null) {
return ref
.read(locationViewModelProvider.notifier)
.read(locationControllerProvider.notifier)
.updateGeofence(
id: editing.id,
name: name,
@@ -337,7 +327,7 @@ class _LocationMapState extends ConsumerState<LocationMap>
);
}
return ref
.read(locationViewModelProvider.notifier)
.read(locationControllerProvider.notifier)
.createGeofence(
name: name,
description: description,
@@ -351,9 +341,9 @@ class _LocationMapState extends ConsumerState<LocationMap>
void _showListSheet() {
unawaited(ref.read(sfTrackingProvider).legacyLocationListSheetOpened());
final locationState = ref.read(locationViewModelProvider).value;
final locationState = ref.read(locationControllerProvider).value;
if (locationState == null) return;
final mapState = ref.read(locationMapViewModelProvider);
final mapState = ref.read(locationMapControllerProvider);
showModalBottomSheet(
context: context,
isScrollControlled: true,
@@ -389,7 +379,7 @@ class _LocationMapState extends ConsumerState<LocationMap>
if (widget.positionHistory.isEmpty) {
_openDateRangePicker();
} else {
ref.read(locationViewModelProvider.notifier).toggleRouteTrail();
ref.read(locationControllerProvider.notifier).toggleRouteTrail();
}
}
@@ -422,7 +412,7 @@ class _LocationMapState extends ConsumerState<LocationMap>
59,
);
ref
.read(locationViewModelProvider.notifier)
.read(locationControllerProvider.notifier)
.loadPositionHistory(from: picked.start, to: to);
}
}
@@ -439,7 +429,7 @@ class _LocationMapState extends ConsumerState<LocationMap>
initialName: fp.name,
submitLabel: context.translate(I18n.locationSave),
onSubmit: (name, _) => ref
.read(locationViewModelProvider.notifier)
.read(locationControllerProvider.notifier)
.updateFrequentPlace(
id: fp.id,
name: name,
@@ -450,7 +440,7 @@ class _LocationMapState extends ConsumerState<LocationMap>
);
}
List<Widget> _buildMapLayers(LocationMapViewState mapState) {
List<Widget> _buildMapLayers(LocationMapState mapState) {
final historyLayer =
widget.showRouteTrail && widget.positionHistory.isNotEmpty
? RouteHistoryLayer(
@@ -512,7 +502,7 @@ class _LocationMapState extends ConsumerState<LocationMap>
}
List<Marker> _buildMarkers(
LocationMapViewState mapState,
LocationMapState mapState,
RouteHistoryLayer? historyLayer,
) {
return [
@@ -599,7 +589,7 @@ class _LocationMapState extends ConsumerState<LocationMap>
];
}
List<Widget> _buildControls(LocationMapViewState mapState) {
List<Widget> _buildControls(LocationMapState mapState) {
if (mapState.placingMode != PlacingMode.none) {
return [
Center(
@@ -696,11 +686,7 @@ class _LocationMapState extends ConsumerState<LocationMap>
);
widget.onRefreshPosition();
if (!mounted) return;
showTopSnackbar(
context,
message: context.translate(I18n.locationMapRefreshRequested),
type: MessageType.info,
);
await showInfoDialog(context, I18n.locationMapRefreshRequested);
},
onCenterTap: _centerOnDevice,
onToggleFollow: () async {
@@ -716,14 +702,11 @@ class _LocationMapState extends ConsumerState<LocationMap>
_centerOnDevice();
}
if (!mounted) return;
showTopSnackbar(
await showSuccessDialog(
context,
message: context.translate(
willActivate
? I18n.locationMapFollowEnabled
: I18n.locationMapFollowDisabled,
),
type: MessageType.success,
willActivate
? I18n.locationMapFollowEnabled
: I18n.locationMapFollowDisabled,
);
},
),
@@ -731,7 +714,7 @@ class _LocationMapState extends ConsumerState<LocationMap>
];
}
List<Widget> _buildInfoCards(LocationMapViewState mapState) {
List<Widget> _buildInfoCards(LocationMapState mapState) {
return [
if (mapState.selectedGeofence != null)
ModalOverlay(
@@ -748,7 +731,7 @@ class _LocationMapState extends ConsumerState<LocationMap>
final id = mapState.selectedGeofence!.id;
_vm.clearSelectedGeofence();
ref
.read(locationViewModelProvider.notifier)
.read(locationControllerProvider.notifier)
.deleteGeofence(id: id);
},
),
@@ -765,7 +748,7 @@ class _LocationMapState extends ConsumerState<LocationMap>
final id = mapState.selectedFrequentPlace!.id;
_vm.clearSelectedFrequentPlace();
ref
.read(locationViewModelProvider.notifier)
.read(locationControllerProvider.notifier)
.deleteFrequentPlace(id: id);
},
),
@@ -783,7 +766,7 @@ class _LocationMapState extends ConsumerState<LocationMap>
@override
Widget build(BuildContext context) {
final mapState = ref.watch(locationMapViewModelProvider);
final mapState = ref.watch(locationMapControllerProvider);
final hasPosition = widget.selectedPosition != null;
final initialCenter = hasPosition
? LatLng(

View File

@@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:location/src/features/location/presentation/state/location_map_view_model.dart';
import 'package:location/src/features/location/presentation/providers/location_map_controller.dart';
import 'package:utils/utils.dart';
import 'map_action_button.dart';
@@ -101,9 +101,9 @@ class FrequencySelector extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final expanded = ref.watch(
locationMapViewModelProvider.select((s) => s.frequencyExpanded),
locationMapControllerProvider.select((s) => s.frequencyExpanded),
);
final vm = ref.read(locationMapViewModelProvider.notifier);
final vm = ref.read(locationMapControllerProvider.notifier);
return AnimatedSize(
duration: const Duration(milliseconds: 200),
@@ -118,7 +118,7 @@ class FrequencySelector extends ConsumerWidget {
);
}
Widget _buildSegmented(BuildContext context, LocationMapViewModel vm) {
Widget _buildSegmented(BuildContext context, LocationMapController vm) {
return Material(
elevation: 2,
borderRadius: BorderRadius.circular(8),

View File

@@ -1,9 +1,10 @@
import 'dart:async';
import 'package:legacy_theme/legacy_theme.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:legacy_theme/legacy_theme.dart';
import 'package:legacy_ui/legacy_ui.dart';
import 'package:location/src/features/location/presentation/providers/map_style_selector_controller.dart';
import 'package:sf_localizations/sf_localizations.dart';
import 'package:sf_tracking/sf_tracking.dart';
@@ -15,28 +16,23 @@ const _labelKeys = {
MapStyle.satellite: I18n.locationMapStyleSatellite,
};
class MapStyleSelector extends ConsumerStatefulWidget {
class MapStyleSelector extends ConsumerWidget {
const MapStyleSelector({super.key});
@override
ConsumerState<MapStyleSelector> createState() => _MapStyleSelectorState();
}
class _MapStyleSelectorState extends ConsumerState<MapStyleSelector> {
bool _expanded = false;
@override
Widget build(BuildContext context) {
Widget build(BuildContext context, WidgetRef ref) {
final currentStyle = ref.watch(mapStyleProvider);
final expanded = ref.watch(mapStyleSelectorExpandedProvider);
final primaryColor = context.sfColors.legacyPrimary;
if (!_expanded) {
if (!expanded) {
return Material(
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.circular(8),
elevation: 2,
child: InkWell(
onTap: () => setState(() => _expanded = true),
onTap: () =>
ref.read(mapStyleSelectorExpandedProvider.notifier).set(true),
borderRadius: BorderRadius.circular(8),
child: const SizedBox(
width: 40,
@@ -72,7 +68,7 @@ class _MapStyleSelectorState extends ConsumerState<MapStyleSelector> {
.read(sfTrackingProvider)
.legacyLocationMapStyleChanged(style.name),
);
setState(() => _expanded = false);
ref.read(mapStyleSelectorExpandedProvider.notifier).set(false);
},
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8),
@@ -84,7 +80,9 @@ class _MapStyleSelectorState extends ConsumerState<MapStyleSelector> {
? Icons.satellite_alt
: Icons.map,
size: 16,
color: isSelected ? primaryColor : Theme.of(context).colorScheme.onSurfaceVariant,
color: isSelected
? primaryColor
: Theme.of(context).colorScheme.onSurfaceVariant,
),
const SizedBox(width: 8),
Text(
@@ -94,7 +92,9 @@ class _MapStyleSelectorState extends ConsumerState<MapStyleSelector> {
fontWeight: isSelected
? FontWeight.w600
: FontWeight.w400,
color: isSelected ? primaryColor : Theme.of(context).colorScheme.onSurface,
color: isSelected
? primaryColor
: Theme.of(context).colorScheme.onSurface,
),
),
],

View File

@@ -118,47 +118,56 @@ class _NameInputSheetContentState extends State<_NameInputSheetContent> {
),
),
const SizedBox(height: 12),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
widget.title,
style: TextStyle(
fontSize: SizeUtils.getByScreen(small: 18, big: 19),
fontWeight: FontWeight.w600,
color: widget.primaryColor,
),
),
TextButton(
onPressed: _canSave
? () async {
Navigator.pop(context);
final name = _nameController.text.trim();
final desc = _descController.text.trim();
await widget.onSubmit(
name,
widget.showDescription && desc.isNotEmpty
? desc
: null,
);
}
: null,
child: Text(
widget.submitLabel,
style: TextStyle(
color: _canSave ? widget.primaryColor : Colors.grey,
fontWeight: FontWeight.w600,
fontSize: SizeUtils.getByScreen(small: 16, big: 17),
AnimatedBuilder(
animation: _nameController,
builder: (context, _) {
final canSave = _canSave;
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
widget.title,
style: TextStyle(
fontSize:
SizeUtils.getByScreen(small: 18, big: 19),
fontWeight: FontWeight.w600,
color: widget.primaryColor,
),
),
),
),
],
TextButton(
onPressed: canSave
? () async {
Navigator.pop(context);
final name = _nameController.text.trim();
final desc = _descController.text.trim();
await widget.onSubmit(
name,
widget.showDescription && desc.isNotEmpty
? desc
: null,
);
}
: null,
child: Text(
widget.submitLabel,
style: TextStyle(
color: canSave
? widget.primaryColor
: Colors.grey,
fontWeight: FontWeight.w600,
fontSize:
SizeUtils.getByScreen(small: 16, big: 17),
),
),
),
],
);
},
),
const SizedBox(height: 12),
TextField(
controller: _nameController,
autofocus: true,
onChanged: (_) => setState(() {}),
decoration: locationInputDecoration(
hintText: widget.hintText,
primaryColor: widget.primaryColor,

View File

@@ -31,6 +31,7 @@ dependencies:
path: ../../../../packages/utils
get_it: ^9.0.5
flutter_riverpod: ^3.0.3
riverpod_annotation: ^3.0.3
go_router: ^17.0.0
freezed_annotation: ^3.1.0
json_annotation: ^4.9.0
@@ -49,6 +50,7 @@ dev_dependencies:
build_runner: ^2.7.1
freezed: ^3.2.3
json_serializable: ^6.11.2
riverpod_generator: ^3.0.3
flutter:
uses-material-design: true