Compare commits

...

12 Commits

Author SHA1 Message Date
94c042d403 manual health measurement command 2026-03-20 15:35:12 +01:00
435a9c04f9 bump build to 5 2026-03-18 21:00:03 +01:00
8e3a27e0d3 feat: add route history, map controls, and geofence/FP management
- Position history with polyline trail and date range picker
  - Map style selector (standard, voyager, light, dark, satellite) persisted via SharedPreferences
  - Geofence and frequent place CRUD with info cards
  - Device banner with swipeable carousel
  - Refresh position button
  - Widget extraction: map controls, info cards, device banner, modal overlay
2026-03-18 19:48:30 +01:00
cf0c55eafe Merge branch 'feature/linked-devices' into fusion-app 2026-03-18 15:09:35 +01:00
03c6633504 fix delete device sizing 2026-03-18 15:09:13 +01:00
b8184f02ec Merge remote-tracking branch 'origin/fusion-app' into fusion-app 2026-03-18 14:56:51 +01:00
c12d1924c4 splash screen fix 2026-03-18 13:52:07 +01:00
869f33f1f1 Merge remote-tracking branch 'origin/feature/change-password' into fusion-app 2026-03-18 13:21:52 +01:00
a07246130e fix change password fields and validation 2026-03-18 13:21:16 +01:00
67aafafd1e hide interceptor for legacy app 2026-03-18 13:15:00 +01:00
c929e1e2d7 beneficiary validation and development api origin fix 2026-03-18 13:13:36 +01:00
990266ba95 delete device command and device setup flow 2026-03-18 11:49:05 +01:00
125 changed files with 12665 additions and 1172 deletions

View File

@@ -1,5 +1,5 @@
{
"env": "development",
"apiBaseUrl": "https://api-neki-b2b.neki.es/gateway/api/",
"apiOrigin": "bde6ea73-d09c-475f-aabf-1d11137e4d0d"
}
"apiOrigin": "https://neki-b2b.neki.es"
}

View File

@@ -543,7 +543,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon-development;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = "Runner/Runner-development.entitlements";
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
@@ -727,7 +727,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon-development;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = "Runner/Runner-development.entitlements";
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
@@ -751,7 +751,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon-development;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = "Runner/Runner-development.entitlements";
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
@@ -1100,7 +1100,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon-staging;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = "Runner/Runner-staging.entitlements";
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
@@ -1124,7 +1124,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon-production;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
@@ -1148,7 +1148,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon-staging;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = "Runner/Runner-staging.entitlements";
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
@@ -1171,7 +1171,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon-production;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
@@ -1194,7 +1194,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon-staging;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = "Runner/Runner-staging.entitlements";
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
@@ -1217,7 +1217,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon-production;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";

View File

@@ -1,5 +1,6 @@
import 'dart:async';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:sf_infrastructure/sf_infrastructure.dart';
@@ -35,8 +36,10 @@ class LegacyHeartbeatService {
debugPrint('[LegacyHeartbeat] /auth/me => OK');
} catch (e) {
debugPrint('[LegacyHeartbeat] error: $e');
stop();
_onUnauthorized();
if (e is DioException && e.response?.statusCode == 401) {
stop();
_onUnauthorized();
}
}
}
}

View File

@@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.0.0+4
version: 1.0.0+5
environment:
sdk: ^3.9.2

View File

@@ -1 +1 @@
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_treezor_entrust_sdk_bridge","path":"C:\\\\dev\\\\sf-app-platform\\\\packages\\\\flutter_treezor_entrust_sdk_bridge\\\\","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_foundation","path":"C:\\\\Users\\\\Aitor Arana\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_foundation-2.5.1\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_foundation","path":"C:\\\\Users\\\\Aitor Arana\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_foundation-2.5.6\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"android":[{"name":"flutter_treezor_entrust_sdk_bridge","path":"C:\\\\dev\\\\sf-app-platform\\\\packages\\\\flutter_treezor_entrust_sdk_bridge\\\\","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_android","path":"C:\\\\Users\\\\Aitor Arana\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_android-2.2.22\\\\","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_android","path":"C:\\\\Users\\\\Aitor Arana\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_android-2.4.20\\\\","native_build":true,"dependencies":[],"dev_dependency":false}],"macos":[{"name":"path_provider_foundation","path":"C:\\\\Users\\\\Aitor Arana\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_foundation-2.5.1\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_foundation","path":"C:\\\\Users\\\\Aitor Arana\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_foundation-2.5.6\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"linux":[{"name":"path_provider_linux","path":"C:\\\\Users\\\\Aitor Arana\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_linux-2.2.1\\\\","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_linux","path":"C:\\\\Users\\\\Aitor Arana\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_linux-2.4.1\\\\","native_build":false,"dependencies":["path_provider_linux"],"dev_dependency":false}],"windows":[{"name":"path_provider_windows","path":"C:\\\\Users\\\\Aitor Arana\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_windows-2.3.0\\\\","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_windows","path":"C:\\\\Users\\\\Aitor Arana\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_windows-2.4.1\\\\","native_build":false,"dependencies":["path_provider_windows"],"dev_dependency":false}],"web":[{"name":"shared_preferences_web","path":"C:\\\\Users\\\\Aitor Arana\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_web-2.4.3\\\\","dependencies":[],"dev_dependency":false}]},"dependencyGraph":[{"name":"flutter_treezor_entrust_sdk_bridge","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]}],"date_created":"2026-03-16 09:33:25.098373","version":"3.35.6","swift_package_manager_enabled":{"ios":false,"macos":false}}
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_treezor_entrust_sdk_bridge","path":"/Users/juliandalcalaf/Desktop/save-family-app/sf-app-platform/packages/flutter_treezor_entrust_sdk_bridge/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_foundation","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_foundation-2.5.1/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_foundation","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.6/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"android":[{"name":"flutter_treezor_entrust_sdk_bridge","path":"/Users/juliandalcalaf/Desktop/save-family-app/sf-app-platform/packages/flutter_treezor_entrust_sdk_bridge/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_android","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_android-2.2.22/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_android","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences_android-2.4.20/","native_build":true,"dependencies":[],"dev_dependency":false}],"macos":[{"name":"path_provider_foundation","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_foundation-2.5.1/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_foundation","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.6/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"linux":[{"name":"path_provider_linux","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_linux","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences_linux-2.4.1/","native_build":false,"dependencies":["path_provider_linux"],"dev_dependency":false}],"windows":[{"name":"path_provider_windows","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_windows-2.3.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_windows","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences_windows-2.4.1/","native_build":false,"dependencies":["path_provider_windows"],"dev_dependency":false}],"web":[{"name":"shared_preferences_web","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences_web-2.4.3/","dependencies":[],"dev_dependency":false}]},"dependencyGraph":[{"name":"flutter_treezor_entrust_sdk_bridge","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]}],"date_created":"2026-03-18 14:45:38.408085","version":"3.35.7","swift_package_manager_enabled":{"ios":false,"macos":false}}

View File

@@ -1,7 +1,7 @@
import 'package:account/src/features/linked_devices/domain/entities/update_device_request_entity.dart';
abstract class DevicesRemoteDatasource {
Future<void> deleteDevice({required String userId, required String deviceId});
Future<void> deleteDevice({required String deviceId});
Future<void> updateDevice({required String userId, required UpdateDeviceRequestEntity request});
Future<void> updateDevice({required UpdateDeviceRequestEntity request});
}

View File

@@ -12,7 +12,7 @@ class DevicesRemoteDatasourceImpl implements DevicesRemoteDatasource {
final QuestiaRepository _repository;
@override
Future<void> deleteDevice({required String userId, required String deviceId}) async {
Future<void> deleteDevice({required String deviceId}) async {
try {
await _repository.delete<void>(
'/devices/$deviceId',
@@ -23,7 +23,7 @@ class DevicesRemoteDatasourceImpl implements DevicesRemoteDatasource {
}
@override
Future<void> updateDevice({required String userId, required UpdateDeviceRequestEntity request}) async {
Future<void> updateDevice({required UpdateDeviceRequestEntity request}) async {
try {
final body = request.toModel().toJson();
await _repository.put<void>(

View File

@@ -9,12 +9,12 @@ class DevicesRepositoryImpl implements DevicesRepository {
final DevicesRemoteDatasource _remote;
@override
Future<void> deleteDevice({required String userId, required String deviceId}) {
return _remote.deleteDevice(userId: userId, deviceId: deviceId);
Future<void> deleteDevice({required String deviceId}) {
return _remote.deleteDevice(deviceId: deviceId);
}
@override
Future<void> updateDevice({required String userId, required UpdateDeviceRequestEntity request}) {
return _remote.updateDevice(userId: userId, request: request);
Future<void> updateDevice({required UpdateDeviceRequestEntity request}) {
return _remote.updateDevice(request: request);
}
}

View File

@@ -1,10 +1,9 @@
import 'package:account/src/features/linked_devices/domain/entities/update_device_request_entity.dart';
abstract class DevicesRepository {
Future<void> deleteDevice({required String userId, required String deviceId});
Future<void> deleteDevice({required String deviceId});
Future<void> updateDevice({
required String userId,
required UpdateDeviceRequestEntity request
});
}

View File

@@ -16,6 +16,9 @@ class ChangePasswordScreen extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final theme = ref.watch(themePortProvider);
final password = ref.watch(
changePasswordViewModelProvider.select((s)=>s.newPassword)
);
return LegacyPageLayout(
theme: theme,
@@ -28,11 +31,11 @@ class ChangePasswordScreen extends ConsumerWidget {
child: SingleChildScrollView(child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const _PasswordSection(),
SizedBox(height: SizeUtils.getByScreen(small: 24, big: 22)),
const _NewPasswordSection(),
SizedBox(height: SizeUtils.getByScreen(small: 24, big: 22)),
const _RepeatPasswordSection(),
SizedBox(height: SizeUtils.getByScreen(small: 24, big: 22)),
_PasswordCriteriaList(password: password),
const _ErrorMessageSection()
],
))
@@ -42,29 +45,6 @@ class ChangePasswordScreen extends ConsumerWidget {
}
}
class _PasswordSection extends ConsumerWidget {
const _PasswordSection();
@override
Widget build(BuildContext context, WidgetRef ref) {
final vm = ref.read(changePasswordViewModelProvider.notifier);
final showPassword = ref.watch(
changePasswordViewModelProvider.select((s)=>s.showCurrentPassword)
);
return CustomTextField(
controller: vm.currentPasswordController,
hint: '********',
label: context.translate(I18n.password),
showPassword: showPassword,
onVisibilityChanged: vm.toggleCurrentPasswordVisibility,
);
}
}
class _NewPasswordSection extends ConsumerWidget {
const _NewPasswordSection();
@@ -111,6 +91,89 @@ class _RepeatPasswordSection extends ConsumerWidget {
}
class _PasswordCriteriaList extends StatelessWidget {
final String password;
const _PasswordCriteriaList({required this.password});
static final _upperRegex = RegExp(r'[A-Z]');
static final _digitRegex = RegExp(r'[0-9]');
static final _specialRegex =
RegExp(r'[!@#$%^&*(),.?":{}|<>\-_+=\[\]\\\/~`]');
@override
Widget build(BuildContext context) {
final hasInput = password.isNotEmpty;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
spacing: 6,
children: [
_CriteriaRow(
label: context.translate(I18n.passwordLength),
met: password.length >= 8,
hasInput: hasInput,
),
_CriteriaRow(
label: context.translate(I18n.passwordCapital),
met: _upperRegex.hasMatch(password),
hasInput: hasInput,
),
_CriteriaRow(
label: context.translate(I18n.passwordNumber),
met: _digitRegex.hasMatch(password),
hasInput: hasInput,
),
_CriteriaRow(
label: context.translate(I18n.passwordSpecial),
met: _specialRegex.hasMatch(password),
hasInput: hasInput,
),
],
);
}
}
class _CriteriaRow extends StatelessWidget {
final String label;
final bool met;
final bool hasInput;
const _CriteriaRow({
required this.label,
required this.met,
required this.hasInput,
});
@override
Widget build(BuildContext context) {
final Color color;
final IconData icon;
if (!hasInput) {
color = Colors.grey;
icon = Icons.circle_outlined;
} else if (met) {
color = Colors.green;
icon = Icons.check_circle;
} else {
color = Colors.red.shade400;
icon = Icons.cancel;
}
return Row(
spacing: 8,
children: [
Icon(icon, size: 16, color: color),
Text(
label,
style: TextStyle(fontSize: 13, color: color),
),
],
);
}
}
class _ErrorMessageSection extends ConsumerWidget {
const _ErrorMessageSection();
@@ -136,7 +199,9 @@ class _ErrorMessageSection extends ConsumerWidget {
),
],
);
} else return SizedBox.shrink();
} else {
return SizedBox.shrink();
}
}
}

View File

@@ -14,7 +14,6 @@ NotifierProvider.autoDispose<ChangePasswordViewModel, ChangePasswordViewState>(
class ChangePasswordViewModel extends Notifier<ChangePasswordViewState> {
late final ChangePasswordUseCase _changePasswordUseCase;
late final TextEditingController currentPasswordController;
late final TextEditingController newPasswordController;
late final TextEditingController repeatPasswordController;
late final TextEditingController passwordController;
@@ -29,10 +28,6 @@ class ChangePasswordViewModel extends Notifier<ChangePasswordViewState> {
}
void _initControllers() {
currentPasswordController = TextEditingController();
currentPasswordController.addListener(_onCurrentPasswordChanged);
newPasswordController = TextEditingController();
newPasswordController.addListener(_onNewPasswordChanged);
@@ -60,17 +55,6 @@ class ChangePasswordViewModel extends Notifier<ChangePasswordViewState> {
);
}
void _onCurrentPasswordChanged() {
final value = currentPasswordController.text;
if (value == state.currentPassword) return;
state = state.copyWith(
currentPassword: value,
errorMessage: ''
);
}
void _onNewPasswordChanged() {
final value = newPasswordController.text;
@@ -94,11 +78,14 @@ class ChangePasswordViewModel extends Notifier<ChangePasswordViewState> {
}
bool _validateForm() {
if (state.currentPassword.trim().isEmpty){
state = state.copyWith(errorMessage: 'errorMessageCurrentPasswordIsEmpty');
return false;
}
if (state.newPassword.trim().isEmpty){
final _upperRegex = RegExp(r'[A-Z]');
final _digitRegex = RegExp(r'[0-9]');
final _specialRegex =
RegExp(r'[!@#$%^&*(),.?":{}|<>\-_+=\[\]\\\/~`]');
final password = state.newPassword.trim();
if (password.isEmpty){
state = state.copyWith(errorMessage: 'errorMessageNewPasswordIsEmpty');
return false;
}
@@ -106,10 +93,26 @@ class ChangePasswordViewModel extends Notifier<ChangePasswordViewState> {
state = state.copyWith(errorMessage: 'errorMessageRepeatPasswordIsEmpty');
return false;
}
if (state.newPassword.trim() != state.repeatPassword.trim()){
if (password != state.repeatPassword.trim()){
state = state.copyWith(errorMessage: 'errorMessagePasswordsDontMatch');
return false;
}
if (password.length < 8){
state = state.copyWith(errorMessage: 'errorPasswordMinLength');
return false;
}
if (!_upperRegex.hasMatch(password)) {
state = state.copyWith(errorMessage: 'errorPasswordUppercase');
return false;
}
if (!_digitRegex.hasMatch(password)) {
state = state.copyWith(errorMessage: 'errorPasswordDigits');
return false;
}
if (!_specialRegex.hasMatch(password)) {
state = state.copyWith(errorMessage: 'errorPasswordSpecial');
return false;
}
return true;
}
@@ -155,9 +158,6 @@ class ChangePasswordViewModel extends Notifier<ChangePasswordViewState> {
}
void disposeControllers() {
currentPasswordController.removeListener(_onCurrentPasswordChanged);
currentPasswordController.dispose();
newPasswordController.removeListener(_onNewPasswordChanged);
newPasswordController.dispose();

View File

@@ -7,10 +7,8 @@ abstract class ChangePasswordViewState with _$ChangePasswordViewState {
const factory ChangePasswordViewState({
@Default(false) bool isLoading,
@Default(false) bool isComplete,
@Default(false) bool showCurrentPassword,
@Default(false) bool showNewPassword,
@Default(false) bool showRepeatedPassword,
@Default('') String currentPassword,
@Default('') String newPassword,
@Default('') String repeatPassword,
@Default('') String errorMessage

View File

@@ -27,16 +27,20 @@ class LinkedDevicesScreen extends ConsumerWidget {
title: context.translate(I18n.linkedDevices),
showEdit: true,
onEditChange: vm.toggleIsEditing,
body: ListView.separated(
itemBuilder: (BuildContext context, int index)=>_LinkedDeviceCard(
device: state.linkedDevices[index],
isEditing: state.isEditing,
onDelete: ()=>vm.deleteDevice(state.linkedDevices[index]),
body: Padding(
padding: EdgeInsets.symmetric(horizontal: SizeUtils.getByScreen(small: 10, big: 12)),
child: ListView.separated(
itemBuilder: (BuildContext context, int index)=>_LinkedDeviceCard(
navigationContract: navigationContract,
device: state.linkedDevices[index],
isEditing: state.isEditing,
onDelete: ()=>vm.deleteDevice(state.linkedDevices[index]),
),
separatorBuilder: (BuildContext context, int index)=>SizedBox(
height: SizeUtils.getByScreen(small: 18, big: 17)
),
itemCount: state.linkedDevices.length
),
separatorBuilder: (BuildContext context, int index)=>SizedBox(
height: SizeUtils.getByScreen(small: 18, big: 17)
),
itemCount: state.linkedDevices.length
),
);
}
@@ -44,11 +48,13 @@ class LinkedDevicesScreen extends ConsumerWidget {
class _LinkedDeviceCard extends ConsumerWidget {
final NavigationContract navigationContract;
final DeviceEntity device;
final bool isEditing;
final Function onDelete;
const _LinkedDeviceCard({
required this.navigationContract,
required this.device,
required this.isEditing,
required this.onDelete,
@@ -76,7 +82,7 @@ class _LinkedDeviceCard extends ConsumerWidget {
shape: BoxShape.circle,
color: theme.getColorFor(ThemeCode.backgroundPrimary),
),
padding: EdgeInsets.all(SizeUtils.getByScreen(small: 4, big: 12)),
padding: EdgeInsets.all(SizeUtils.getByScreen(small: 8, big: 12)),
child: Icon(SFIcons.watch,
size: SizeUtils.getByScreen(small: 40, big: 44),
color: theme.getColorFor(ThemeCode.legacyPrimary),
@@ -110,7 +116,10 @@ class _LinkedDeviceCard extends ConsumerWidget {
),
child: IconButton(
onPressed: (){showDialog(context: context, builder: (context)=>Dialog(
child: DeleteDeviceDialog(device: device),
child: DeleteDeviceDialog(
navigationContract: navigationContract,
device: device,
),
));},
icon: Icon(
Icons.close,

View File

@@ -70,19 +70,32 @@ class LinkedDevicesViewModel extends Notifier<LinkedDevicesViewState> {
);
}
Future<bool> deleteDevice(DeviceEntity device) async {
Future<void> deleteDevice(DeviceEntity device) async {
try {
await _devicesRepository.deleteDevice(userId: state.loggedUser!.id, deviceId: device.identificator);
List<DeviceEntity> newList = state.linkedDevices;
newList.remove(device);
state = state.copyWith(
linkedDevices: newList
isLoading: true,
isComplete: false,
);
return true;
await _devicesRepository.deleteDevice(deviceId: device.id);
List<DeviceEntity> newList = state.linkedDevices.toList();
newList.remove(device);
if (device == state.selectedDevice) {
ref.invalidate(selectedDeviceProvider);
}
state = state.copyWith(
linkedDevices: newList,
isLoading: false,
isComplete: true,
);
} catch (e) {
return false;
state = state.copyWith(
isLoading: false,
errorMessage: e.toString(),
);
return;
}
}
@@ -102,9 +115,7 @@ class LinkedDevicesViewModel extends Notifier<LinkedDevicesViewState> {
if (deviceName.isEmpty) return;
try {
final userId = state.loggedUser!.id;
_devicesRepository.updateDevice(
userId: userId,
request: _toRequest(device));
} catch(e) {
@@ -114,8 +125,6 @@ class LinkedDevicesViewModel extends Notifier<LinkedDevicesViewState> {
errorMessage: e.toString()
);
}
}
void disposeControllers() {

View File

@@ -2,15 +2,20 @@ import 'package:account/src/features/linked_devices/presentation/state/linked_de
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:navigation/navigation.dart';
import 'package:sf_localizations/sf_localizations.dart';
import 'package:sf_shared/sf_shared.dart';
import 'package:utils/utils.dart';
class DeleteDeviceDialog extends ConsumerWidget {
final NavigationContract navigationContract;
final DeviceEntity device;
const DeleteDeviceDialog({required this.device});
const DeleteDeviceDialog({
required this.navigationContract,
required this.device
});
@override
Widget build(BuildContext context, WidgetRef ref) {
@@ -21,15 +26,15 @@ class DeleteDeviceDialog extends ConsumerWidget {
return Container(
padding: SizeUtils.getByScreen(
small: EdgeInsets.symmetric(horizontal: 32, vertical: 30),
big: EdgeInsets.symmetric(horizontal: 30, vertical: 28)
big: EdgeInsets.symmetric(horizontal: 24, vertical: 18)
),
width: SizeUtils.getByScreen(small: 360, big: 350),
height: SizeUtils.getByScreen(small: 195, big: 185),
height: SizeUtils.getByScreen(small: 184, big: 160),
child: Column(
children: [
Text(context.translate(I18n.deleteDeviceDialog),
textAlign: TextAlign.center,
style: TextStyle(fontSize: SizeUtils.getByScreen(small: 19, big: 18)),
style: TextStyle(fontSize: SizeUtils.getByScreen(small: 17, big: 16)),
),
SizedBox(height: SizeUtils.getByScreen(small: 28, big: 27)),
Row(
@@ -46,7 +51,20 @@ class DeleteDeviceDialog extends ConsumerWidget {
Expanded(child: PrimaryButton(
onPressed: () async {
await vm.deleteDevice(device);
Navigator.pop(context);
final isComplete = ref.read(
linkedDevicesViewModelProvider.select((s)=>s.isComplete)
);
if (isComplete) {
Navigator.pop(context);
}
final noMoreDevices = ref.read(
linkedDevicesViewModelProvider.select((s)=>s.linkedDevices)
).isEmpty;
if (noMoreDevices) {
navigationContract.goTo(AppRoutes.legacyDeviceSetup);
}
},
text: context.translate(I18n.delete),
color: theme.getColorFor(ThemeCode.legacyPrimary),

View File

@@ -1,3 +1,9 @@
export 'src/core/data/models/latest_positions_response_model.dart';
export 'src/core/domain/entities/address_entity.dart';
export 'src/core/domain/entities/network_entity.dart';
export 'src/core/domain/entities/position_entity.dart';
export 'src/core/utils/battery_utils.dart';
export 'src/core/utils/date_format_utils.dart';
export 'src/features/control_panel/control_panel_builder.dart';
export 'src/features/control_panel/presentation/state/control_panel_view_model.dart';
export 'src/shared/widgets/device_map.dart';

View File

@@ -258,7 +258,6 @@ class _MapSection extends ConsumerWidget {
child: DeviceMap(
selectedPosition: state.selectedPosition,
selectedDevice: state.selectedDevice,
markerSize: 40,
),
),
),

View File

@@ -5,25 +5,21 @@ 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';
import 'package:flutter_svg/svg.dart';
import 'package:latlong2/latlong.dart';
import 'package:legacy_shared/legacy_shared.dart';
import 'package:sf_shared/sf_shared.dart';
import 'package:utils/utils.dart';
const _defaultCenter = LatLng(40.4168, -3.7038);
const _defaultZoom = 15.0;
const _tileServerUrl = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png';
class DeviceMap extends ConsumerStatefulWidget {
final PositionEntity? selectedPosition;
final DeviceEntity? selectedDevice;
final double markerSize;
const DeviceMap({
super.key,
required this.selectedPosition,
required this.selectedDevice,
this.markerSize = 80,
});
@override
@@ -62,6 +58,7 @@ class _DeviceMapState extends ConsumerState<DeviceMap> {
@override
Widget build(BuildContext context) {
final mapStyle = ref.watch(mapStyleProvider);
final initialCenter = widget.selectedPosition != null
? LatLng(
widget.selectedPosition!.latitude,
@@ -78,7 +75,7 @@ class _DeviceMapState extends ConsumerState<DeviceMap> {
),
children: [
TileLayer(
urlTemplate: _tileServerUrl,
urlTemplate: mapStyle.urlTemplate,
userAgentPackageName: 'com.savefamily.sf_platform',
),
MarkerLayer(
@@ -89,15 +86,9 @@ class _DeviceMapState extends ConsumerState<DeviceMap> {
widget.selectedPosition!.latitude,
widget.selectedPosition!.longitude,
),
width: widget.markerSize * 2.5,
height: widget.markerSize * 1.8,
child: Align(
alignment: Alignment.topCenter,
child: SvgPicture.asset(
'assets/shared/images/location.svg',
height: widget.markerSize,
),
),
width: 100,
height: 100,
child: const PulsingLocationMarker(),
rotate: true,
),
],
@@ -107,7 +98,7 @@ class _DeviceMapState extends ConsumerState<DeviceMap> {
alignment: Alignment.bottomCenter,
child: LocationBanner(
position: widget.selectedPosition!,
battery: widget.selectedDevice?.battery ?? 0,
device: widget.selectedDevice,
),
),
],
@@ -117,86 +108,156 @@ class _DeviceMapState extends ConsumerState<DeviceMap> {
class LocationBanner extends ConsumerWidget {
final PositionEntity position;
final int battery;
final DeviceEntity? device;
const LocationBanner({
super.key,
required this.position,
required this.battery,
this.device,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
final theme = ref.read(themePortProvider);
final batteryIcon = toBatteryIcon(battery);
final primaryColor = theme.getColorFor(ThemeCode.legacyPrimary);
final batteryValue = device?.battery ?? 0;
final batteryIcon = toBatteryIcon(batteryValue);
final dateText = formatPositionDate(position.positionDate);
final localDevice = device;
final name = localDevice?.carrierName;
final deviceName = localDevice != null
? (name != null && name.isNotEmpty ? name : localDevice.identificator)
: null;
final initial = deviceName != null && deviceName.isNotEmpty
? deviceName[0].toUpperCase()
: null;
final addressText = [
position.address?.street,
position.address?.province,
position.address?.country,
].whereType<String>().where((s) => s.isNotEmpty).join(', ');
return Container(
height: SizeUtils.getByScreen(small: 60, big: 58),
width: SizeUtils.getByScreen(small: 300, big: 298),
margin: EdgeInsets.only(
bottom: SizeUtils.getByScreen(small: 20, big: 16),
),
decoration: BoxDecoration(
color: theme.getColorFor(ThemeCode.backgroundPrimary),
borderRadius: BorderRadius.all(
Radius.circular(SizeUtils.getByScreen(small: 9, big: 8)),
),
),
child: Row(
children: [
Icon(
SFIcons.location,
size: SizeUtils.getByScreen(small: 40, big: 38),
color: theme.getColorFor(ThemeCode.legacyPrimary),
return LayoutBuilder(
builder: (context, constraints) {
final isCompact = constraints.maxWidth < 320;
return Container(
width: isCompact ? constraints.maxWidth * 0.85 : 340,
margin: EdgeInsets.only(bottom: isCompact ? 8 : 16),
padding: EdgeInsets.symmetric(
horizontal: isCompact ? 8 : 12,
vertical: isCompact ? 6 : 10,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
addressText,
overflow: TextOverflow.ellipsis,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(isCompact ? 10 : 16),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.1),
blurRadius: isCompact ? 6 : 10,
offset: const Offset(0, 2),
),
],
),
child: Row(
children: [
if (initial != null)
Container(
width: isCompact ? 30 : 42,
height: isCompact ? 30 : 42,
decoration: BoxDecoration(
color: primaryColor.withValues(alpha: 0.12),
shape: BoxShape.circle,
),
child: Center(
child: Text(
initial,
style: TextStyle(
fontSize: isCompact ? 13 : 18,
fontWeight: FontWeight.w700,
color: primaryColor,
),
),
),
),
Row(
SizedBox(width: isCompact ? 6 : 10),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Flexible(
child: Text(
dateText,
if (deviceName != null)
Text(
deviceName,
style: TextStyle(
fontSize: SizeUtils.getByScreen(small: 12, big: 11),
fontSize: isCompact ? 12 : 14,
fontWeight: FontWeight.w600,
color: Colors.grey.shade800,
),
overflow: TextOverflow.ellipsis,
),
),
if (position.networks.isNotEmpty)
Text(
' | ${position.networks.first.signal}',
style: TextStyle(
fontSize: SizeUtils.getByScreen(small: 12, big: 11),
if (addressText.isNotEmpty)
Padding(
padding: EdgeInsets.only(
top: deviceName != null ? 1 : 0),
child: Text(
addressText,
style: TextStyle(
fontSize: isCompact ? 9 : 11,
color: Colors.grey.shade500,
),
overflow: TextOverflow.ellipsis,
),
),
Icon(batteryIcon),
Text(
'$battery%',
style: TextStyle(
fontSize: SizeUtils.getByScreen(small: 12, big: 11),
),
),
],
),
],
),
),
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
batteryIcon,
size: isCompact ? 13 : 16,
color: batteryValue > 20
? primaryColor
: Colors.orange,
),
const SizedBox(width: 2),
Text(
'$batteryValue%',
style: TextStyle(
fontSize: isCompact ? 10 : 12,
fontWeight: FontWeight.w600,
color: batteryValue > 20
? primaryColor
: Colors.orange,
),
),
],
),
if (!isCompact)
Padding(
padding: const EdgeInsets.only(top: 3),
child: Text(
dateText,
style: TextStyle(
fontSize: 10,
color: Colors.grey.shade400,
),
),
),
],
),
],
),
],
),
);
},
);
}
}

View File

@@ -130,6 +130,31 @@ class _HealthScreenState extends ConsumerState<HealthScreen>
),
],
),
footer: _SaveSection()
);
}
}
class _SaveSection extends ConsumerWidget{
const _SaveSection();
@override
Widget build(BuildContext context, WidgetRef ref) {
final theme = ref.read(themePortProvider);
final vm = ref.read(healthViewModelProvider.notifier);
return Padding(
padding: EdgeInsets.symmetric(horizontal: 24, vertical: 10),
child:
PrimaryButton(
onPressed: () async {
await vm.measure();
},
text: context.translate(I18n.measure),
color: theme.getColorFor(ThemeCode.legacyPrimary)
)
);
}
}

View File

@@ -14,12 +14,14 @@ final healthViewModelProvider =
class HealthViewModel extends Notifier<HealthViewState> {
late final HealthRepository _repository;
late final CommandsRepository _commandsRepository;
static const int _historyPageSize = 20;
@override
HealthViewState build() {
_repository = ref.read(healthRepositoryProvider);
_commandsRepository = ref.read(commandsRepositoryProvider);
_init();
return const HealthViewState();
}
@@ -243,4 +245,32 @@ class HealthViewModel extends Notifier<HealthViewState> {
final msg = e.toString();
return msg.startsWith('Exception: ') ? msg.substring(11) : msg;
}
Future<void> measure() async {
try {
state = state.copyWith(
isLoading: true,
);
final device = ref.read(selectedDeviceProvider);
if (device == null) return;
final request = SendCommandRequestModel(
device: device.identificator,
command: DeviceCommand.requestHeartRate,
);
await _commandsRepository.send(request: request);
state = state.copyWith(
isLoading: false,
);
} catch (e) {
state = state.copyWith(
isLoading: false,
errorMessage: e.toString(),
);
}
}
}

View File

@@ -8,6 +8,9 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:navigation/navigation_contract.dart';
import 'package:sf_localizations/sf_localizations.dart';
import 'package:utils/utils.dart';
import 'widgets/activation_code_dialog.dart';
class LegacyDeviceSetupScreen extends ConsumerWidget {
final NavigationContract navigationContract;
@@ -54,7 +57,7 @@ class LegacyDeviceSetupScreen extends ConsumerWidget {
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 12, left: 8, right: 8),
padding: EdgeInsets.only(top: SizeUtils.getByScreen(small: 4, big: 12), left: 8, right: 8),
child: Row(
children: [
if (isIntro)
@@ -114,6 +117,9 @@ class LegacyDeviceSetupScreen extends ConsumerWidget {
}
return;
}
if (state.step == LegacyAddKidStep.scanWatch) {
showActivationCodeDialog(context);
}
await vm.next();
},
theme: theme,

View File

@@ -3,6 +3,7 @@ import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:sf_localizations/sf_localizations.dart';
import 'package:utils/utils.dart';
class LegacyIntroStepScreen extends ConsumerWidget {
const LegacyIntroStepScreen({super.key});
@@ -11,29 +12,34 @@ class LegacyIntroStepScreen extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final theme = ref.watch(themePortProvider);
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
context.translate(I18n.deviceSetup_intro_title),
style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
),
const SizedBox(height: 30),
Text(
context.translate(I18n.deviceSetup_intro_subtitle),
style: TextStyle(fontSize: 18),
textAlign: TextAlign.center,
),
SizedBox(height: 40),
LegacyNumberedSteps(
steps: [
context.translate(I18n.deviceSetup_intro_step_1),
context.translate(I18n.deviceSetup_intro_step_2),
],
color: theme.getColorFor(ThemeCode.legacyPrimary),
),
],
return Padding(
padding: EdgeInsets.symmetric(
horizontal: SizeUtils.getByScreen(small: 8, big: 2)
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
context.translate(I18n.deviceSetup_intro_title),
style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
),
const SizedBox(height: 30),
Text(
context.translate(I18n.deviceSetup_intro_subtitle),
style: TextStyle(fontSize: 18),
textAlign: TextAlign.center,
),
SizedBox(height: 40),
LegacyNumberedSteps(
steps: [
context.translate(I18n.deviceSetup_intro_step_1),
context.translate(I18n.deviceSetup_intro_step_2),
],
color: theme.getColorFor(ThemeCode.legacyPrimary),
),
],
),
);
}
}

View File

@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:sf_localizations/sf_localizations.dart';
import 'package:utils/utils.dart';
class LegacyLinkInfoStepScreen extends ConsumerWidget {
const LegacyLinkInfoStepScreen({super.key});
@@ -13,7 +14,7 @@ class LegacyLinkInfoStepScreen extends ConsumerWidget {
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(height: 30),
SizedBox(height: SizeUtils.getByScreen(small: 8, big: 30)),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 65),
child: Text(

View File

@@ -147,7 +147,7 @@ class LegacyProfileStepScreen extends ConsumerWidget {
CustomTextField(
label: context.translate(I18n.activationKeyLabel),
hint: 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX',
hint: 'XXXXXXXX',
controller: vm.activationKeyController,
),

View File

@@ -0,0 +1,33 @@
import 'package:flutter/material.dart';
import 'package:sf_localizations/sf_localizations.dart';
import 'package:utils/utils.dart';
void showActivationCodeDialog(BuildContext context) {
showDialog(context: context, builder: (context) =>
Dialog(
backgroundColor: Colors.transparent,
child: _ActivationCodeDialog(),
)
);
}
class _ActivationCodeDialog extends StatelessWidget {
const _ActivationCodeDialog();
@override
Widget build(BuildContext context) {
return Container(
padding: SizeUtils.getByScreen(
small: EdgeInsets.symmetric(horizontal: 14, vertical: 24),
big: EdgeInsets.symmetric(horizontal: 12, vertical: 20),
),
color: Colors.white,
child: Text(context.translate(I18n.activationCodeMessage),
textAlign: TextAlign.center,
style: TextStyle(fontSize: SizeUtils.getByScreen(small: 16, big: 15)),
),
);
}
}

View File

@@ -3,6 +3,7 @@ import 'dart:async';
import 'package:legacy_auth/src/features/login/presentation/widgets/otp_code_fields.dart';
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:utils/utils.dart';
class LegacyTwoFactorBottomSheetView extends StatelessWidget {
const LegacyTwoFactorBottomSheetView({
@@ -88,6 +89,7 @@ class LegacyTwoFactorBottomSheetView extends StatelessWidget {
if (isOtpLoading || !_isValidOtp) return;
unawaited(onVerify());
},
gap: SizeUtils.getByScreen(small: 10, big: 8),
),
const SizedBox(height: 20),

View File

@@ -0,0 +1,25 @@
import 'package:control_panel/control_panel.dart';
import 'package:location/src/core/data/models/create_frequent_place_request_model.dart';
import 'package:location/src/core/data/models/create_geofence_request_model.dart';
import 'package:location/src/core/data/models/update_frequent_place_request_model.dart';
import 'package:location/src/core/data/models/update_geofence_request_model.dart';
import 'package:location/src/core/domain/entities/geofence_entity.dart';
import 'package:location/src/core/domain/entities/frequent_place_entity.dart';
abstract class LocationRemoteDatasource {
Future<List<GeofenceEntity>> getGeofences({required String deviceId});
Future<GeofenceEntity> createGeofence({required CreateGeofenceRequestModel request});
Future<GeofenceEntity> updateGeofence({required UpdateGeofenceRequestModel request});
Future<void> deleteGeofence({required String geofenceId});
Future<List<FrequentPlaceEntity>> getFrequentPlaces({required String deviceId});
Future<FrequentPlaceEntity> createFrequentPlace({required CreateFrequentPlaceRequestModel request});
Future<FrequentPlaceEntity> updateFrequentPlace({required UpdateFrequentPlaceRequestModel request});
Future<void> deleteFrequentPlace({required String frequentPlaceId});
Future<List<PositionEntity>> getPositionHistory({
required String deviceIdentificator,
required DateTime from,
required DateTime to,
});
}

View File

@@ -0,0 +1,204 @@
import 'dart:convert';
import 'package:control_panel/control_panel.dart';
import 'package:dio/dio.dart';
import 'package:legacy_shared/legacy_shared.dart';
import 'package:location/src/core/data/datasource/location_remote_datasource.dart';
import 'package:location/src/core/data/models/create_frequent_place_request_model.dart';
import 'package:location/src/core/data/models/create_frequent_place_response_model.dart';
import 'package:location/src/core/data/models/create_geofence_request_model.dart';
import 'package:location/src/core/data/models/create_geofence_response_model.dart';
import 'package:location/src/core/data/models/position_history_response_model.dart';
import 'package:location/src/core/data/models/update_frequent_place_request_model.dart';
import 'package:location/src/core/data/models/update_frequent_place_response_model.dart';
import 'package:location/src/core/data/models/update_geofence_request_model.dart';
import 'package:location/src/core/data/models/update_geofence_response_model.dart';
import 'package:location/src/core/data/models/geofences_response_model.dart';
import 'package:location/src/core/data/models/frequent_places_response_model.dart';
import 'package:location/src/core/domain/entities/geofence_entity.dart';
import 'package:location/src/core/domain/entities/frequent_place_entity.dart';
import 'package:sf_infrastructure/sf_infrastructure.dart';
class LocationRemoteDatasourceImpl implements LocationRemoteDatasource {
LocationRemoteDatasourceImpl(this._repository);
final QuestiaRepository _repository;
@override
Future<List<GeofenceEntity>> getGeofences({
required String deviceId,
}) async {
try {
final response = await _repository.get<Map<String, dynamic>>(
'/devices/$deviceId/geofences',
);
final data = response.data;
if (data == null || data.isEmpty) return [];
final model = GeofencesResponseModel.fromJson(data);
return model.toEntity();
} on DioException catch (e) {
if (e.response?.statusCode == 404) return [];
throw mapDioError(e, defaultMessage: 'Error getting geofences');
}
}
@override
Future<GeofenceEntity> createGeofence({
required CreateGeofenceRequestModel request,
}) async {
try {
final response = await _repository.post<Map<String, dynamic>>(
'/geofences',
body: request.toJson(),
);
final data = response.data;
if (data == null) throw Exception('Empty response from server');
return CreateGeofenceResponseModel.fromJson(data).toEntity();
} on DioException catch (e) {
throw mapDioError(e, defaultMessage: 'Error creating geofence');
}
}
@override
Future<GeofenceEntity> updateGeofence({
required UpdateGeofenceRequestModel request,
}) async {
try {
final response = await _repository.put<Map<String, dynamic>>(
'/geofences/${request.id}',
body: request.toJson(),
);
final data = response.data;
if (data == null) throw Exception('Empty response from server');
return UpdateGeofenceResponseModel.fromJson(data).toEntity();
} on DioException catch (e) {
throw mapDioError(e, defaultMessage: 'Error updating geofence');
}
}
@override
Future<void> deleteGeofence({required String geofenceId}) async {
try {
await _repository.delete<Map<String, dynamic>>(
'/geofences/$geofenceId',
);
} on DioException catch (e) {
throw mapDioError(e, defaultMessage: 'Error deleting geofence');
}
}
@override
Future<List<FrequentPlaceEntity>> getFrequentPlaces({
required String deviceId,
}) async {
try {
final response = await _repository.get<Map<String, dynamic>>(
'/devices/$deviceId/frequent-places',
);
final data = response.data;
if (data == null || data.isEmpty) return [];
final model = FrequentPlacesResponseModel.fromJson(data);
return model.toEntity();
} on DioException catch (e) {
if (e.response?.statusCode == 404) return [];
throw mapDioError(e, defaultMessage: 'Error getting frequent places');
}
}
@override
Future<FrequentPlaceEntity> createFrequentPlace({
required CreateFrequentPlaceRequestModel request,
}) async {
try {
final response = await _repository.post<Map<String, dynamic>>(
'/frequent-places',
body: request.toJson(),
);
final data = response.data;
if (data == null) throw Exception('Empty response from server');
return CreateFrequentPlaceResponseModel.fromJson(data).toEntity();
} on DioException catch (e) {
throw mapDioError(e, defaultMessage: 'Error creating frequent place');
}
}
@override
Future<FrequentPlaceEntity> updateFrequentPlace({
required UpdateFrequentPlaceRequestModel request,
}) async {
try {
final response = await _repository.put<Map<String, dynamic>>(
'/frequent-places/${request.id}',
body: request.toJson(),
);
final data = response.data;
if (data == null) throw Exception('Empty response from server');
return UpdateFrequentPlaceResponseModel.fromJson(data).toEntity();
} on DioException catch (e) {
throw mapDioError(e, defaultMessage: 'Error updating frequent place');
}
}
@override
Future<void> deleteFrequentPlace({required String frequentPlaceId}) async {
try {
await _repository.delete<Map<String, dynamic>>(
'/frequent-places/$frequentPlaceId',
);
} on DioException catch (e) {
throw mapDioError(e, defaultMessage: 'Error deleting frequent place');
}
}
@override
Future<List<PositionEntity>> getPositionHistory({
required String deviceIdentificator,
required DateTime from,
required DateTime to,
}) async {
try {
final fromMs = from.millisecondsSinceEpoch;
final toMs = to.millisecondsSinceEpoch;
final filters = base64Encode(utf8.encode(jsonEncode([
{'field': 'positionDate', 'operator': 'gte', 'value': fromMs},
{'field': 'positionDate', 'operator': 'lte', 'value': toMs},
])));
final orderBy = base64Encode(utf8.encode(jsonEncode([
{'field': 'positionDate', 'sortDirection': 'ASC'},
])));
final allPositions = <PositionEntity>[];
int currentPage = 1;
int totalPages = 1;
while (currentPage <= totalPages) {
final response = await _repository.get<Map<String, dynamic>>(
'/devices/identificator/$deviceIdentificator/positions',
queryParameters: {
'page': currentPage,
'pageSize': 1000,
'filters': filters,
'orderBy': orderBy,
},
);
final data = response.data;
if (data == null || data.isEmpty) break;
final model = PositionHistoryResponseModel.fromJson(data);
allPositions.addAll(model.toEntity());
totalPages = model.pages;
currentPage++;
}
return allPositions
.where((p) => p.latitude != 0 || p.longitude != 0)
.toList();
} on DioException catch (e) {
if (e.response?.statusCode == 404) return [];
throw mapDioError(e, defaultMessage: 'Error getting position history');
}
}
}

View File

@@ -0,0 +1,25 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:location/src/core/data/models/frequent_places_response_model.dart';
part 'create_frequent_place_request_model.freezed.dart';
part 'create_frequent_place_request_model.g.dart';
@freezed
abstract class CreateFrequentPlaceRequestModel
with _$CreateFrequentPlaceRequestModel {
const factory CreateFrequentPlaceRequestModel({
required String id,
required String name,
required double lat,
required double lng,
@Default([]) List<WifiInfoResponseModel> wifiList,
String? userId,
String? delegationId,
String? groupId,
String? deviceId,
}) = _CreateFrequentPlaceRequestModel;
factory CreateFrequentPlaceRequestModel.fromJson(
Map<String, dynamic> json) =>
_$CreateFrequentPlaceRequestModelFromJson(json);
}

View File

@@ -0,0 +1,307 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// coverage:ignore-file
// 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 'create_frequent_place_request_model.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$CreateFrequentPlaceRequestModel {
String get id; String get name; double get lat; double get lng; List<WifiInfoResponseModel> get wifiList; String? get userId; String? get delegationId; String? get groupId; String? get deviceId;
/// Create a copy of CreateFrequentPlaceRequestModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$CreateFrequentPlaceRequestModelCopyWith<CreateFrequentPlaceRequestModel> get copyWith => _$CreateFrequentPlaceRequestModelCopyWithImpl<CreateFrequentPlaceRequestModel>(this as CreateFrequentPlaceRequestModel, _$identity);
/// Serializes this CreateFrequentPlaceRequestModel to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is CreateFrequentPlaceRequestModel&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.lat, lat) || other.lat == lat)&&(identical(other.lng, lng) || other.lng == lng)&&const DeepCollectionEquality().equals(other.wifiList, wifiList)&&(identical(other.userId, userId) || other.userId == userId)&&(identical(other.delegationId, delegationId) || other.delegationId == delegationId)&&(identical(other.groupId, groupId) || other.groupId == groupId)&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,name,lat,lng,const DeepCollectionEquality().hash(wifiList),userId,delegationId,groupId,deviceId);
@override
String toString() {
return 'CreateFrequentPlaceRequestModel(id: $id, name: $name, lat: $lat, lng: $lng, wifiList: $wifiList, userId: $userId, delegationId: $delegationId, groupId: $groupId, deviceId: $deviceId)';
}
}
/// @nodoc
abstract mixin class $CreateFrequentPlaceRequestModelCopyWith<$Res> {
factory $CreateFrequentPlaceRequestModelCopyWith(CreateFrequentPlaceRequestModel value, $Res Function(CreateFrequentPlaceRequestModel) _then) = _$CreateFrequentPlaceRequestModelCopyWithImpl;
@useResult
$Res call({
String id, String name, double lat, double lng, List<WifiInfoResponseModel> wifiList, String? userId, String? delegationId, String? groupId, String? deviceId
});
}
/// @nodoc
class _$CreateFrequentPlaceRequestModelCopyWithImpl<$Res>
implements $CreateFrequentPlaceRequestModelCopyWith<$Res> {
_$CreateFrequentPlaceRequestModelCopyWithImpl(this._self, this._then);
final CreateFrequentPlaceRequestModel _self;
final $Res Function(CreateFrequentPlaceRequestModel) _then;
/// Create a copy of CreateFrequentPlaceRequestModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = null,Object? lat = null,Object? lng = null,Object? wifiList = null,Object? userId = freezed,Object? delegationId = freezed,Object? groupId = freezed,Object? deviceId = freezed,}) {
return _then(_self.copyWith(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String,lat: null == lat ? _self.lat : lat // ignore: cast_nullable_to_non_nullable
as double,lng: null == lng ? _self.lng : lng // ignore: cast_nullable_to_non_nullable
as double,wifiList: null == wifiList ? _self.wifiList : wifiList // ignore: cast_nullable_to_non_nullable
as List<WifiInfoResponseModel>,userId: freezed == userId ? _self.userId : userId // ignore: cast_nullable_to_non_nullable
as String?,delegationId: freezed == delegationId ? _self.delegationId : delegationId // ignore: cast_nullable_to_non_nullable
as String?,groupId: freezed == groupId ? _self.groupId : groupId // ignore: cast_nullable_to_non_nullable
as String?,deviceId: freezed == deviceId ? _self.deviceId : deviceId // ignore: cast_nullable_to_non_nullable
as String?,
));
}
}
/// Adds pattern-matching-related methods to [CreateFrequentPlaceRequestModel].
extension CreateFrequentPlaceRequestModelPatterns on CreateFrequentPlaceRequestModel {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _CreateFrequentPlaceRequestModel value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _CreateFrequentPlaceRequestModel() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _CreateFrequentPlaceRequestModel value) $default,){
final _that = this;
switch (_that) {
case _CreateFrequentPlaceRequestModel():
return $default(_that);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _CreateFrequentPlaceRequestModel value)? $default,){
final _that = this;
switch (_that) {
case _CreateFrequentPlaceRequestModel() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String name, double lat, double lng, List<WifiInfoResponseModel> wifiList, String? userId, String? delegationId, String? groupId, String? deviceId)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _CreateFrequentPlaceRequestModel() when $default != null:
return $default(_that.id,_that.name,_that.lat,_that.lng,_that.wifiList,_that.userId,_that.delegationId,_that.groupId,_that.deviceId);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String name, double lat, double lng, List<WifiInfoResponseModel> wifiList, String? userId, String? delegationId, String? groupId, String? deviceId) $default,) {final _that = this;
switch (_that) {
case _CreateFrequentPlaceRequestModel():
return $default(_that.id,_that.name,_that.lat,_that.lng,_that.wifiList,_that.userId,_that.delegationId,_that.groupId,_that.deviceId);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String name, double lat, double lng, List<WifiInfoResponseModel> wifiList, String? userId, String? delegationId, String? groupId, String? deviceId)? $default,) {final _that = this;
switch (_that) {
case _CreateFrequentPlaceRequestModel() when $default != null:
return $default(_that.id,_that.name,_that.lat,_that.lng,_that.wifiList,_that.userId,_that.delegationId,_that.groupId,_that.deviceId);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _CreateFrequentPlaceRequestModel implements CreateFrequentPlaceRequestModel {
const _CreateFrequentPlaceRequestModel({required this.id, required this.name, required this.lat, required this.lng, final List<WifiInfoResponseModel> wifiList = const [], this.userId, this.delegationId, this.groupId, this.deviceId}): _wifiList = wifiList;
factory _CreateFrequentPlaceRequestModel.fromJson(Map<String, dynamic> json) => _$CreateFrequentPlaceRequestModelFromJson(json);
@override final String id;
@override final String name;
@override final double lat;
@override final double lng;
final List<WifiInfoResponseModel> _wifiList;
@override@JsonKey() List<WifiInfoResponseModel> get wifiList {
if (_wifiList is EqualUnmodifiableListView) return _wifiList;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_wifiList);
}
@override final String? userId;
@override final String? delegationId;
@override final String? groupId;
@override final String? deviceId;
/// Create a copy of CreateFrequentPlaceRequestModel
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$CreateFrequentPlaceRequestModelCopyWith<_CreateFrequentPlaceRequestModel> get copyWith => __$CreateFrequentPlaceRequestModelCopyWithImpl<_CreateFrequentPlaceRequestModel>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$CreateFrequentPlaceRequestModelToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _CreateFrequentPlaceRequestModel&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.lat, lat) || other.lat == lat)&&(identical(other.lng, lng) || other.lng == lng)&&const DeepCollectionEquality().equals(other._wifiList, _wifiList)&&(identical(other.userId, userId) || other.userId == userId)&&(identical(other.delegationId, delegationId) || other.delegationId == delegationId)&&(identical(other.groupId, groupId) || other.groupId == groupId)&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,name,lat,lng,const DeepCollectionEquality().hash(_wifiList),userId,delegationId,groupId,deviceId);
@override
String toString() {
return 'CreateFrequentPlaceRequestModel(id: $id, name: $name, lat: $lat, lng: $lng, wifiList: $wifiList, userId: $userId, delegationId: $delegationId, groupId: $groupId, deviceId: $deviceId)';
}
}
/// @nodoc
abstract mixin class _$CreateFrequentPlaceRequestModelCopyWith<$Res> implements $CreateFrequentPlaceRequestModelCopyWith<$Res> {
factory _$CreateFrequentPlaceRequestModelCopyWith(_CreateFrequentPlaceRequestModel value, $Res Function(_CreateFrequentPlaceRequestModel) _then) = __$CreateFrequentPlaceRequestModelCopyWithImpl;
@override @useResult
$Res call({
String id, String name, double lat, double lng, List<WifiInfoResponseModel> wifiList, String? userId, String? delegationId, String? groupId, String? deviceId
});
}
/// @nodoc
class __$CreateFrequentPlaceRequestModelCopyWithImpl<$Res>
implements _$CreateFrequentPlaceRequestModelCopyWith<$Res> {
__$CreateFrequentPlaceRequestModelCopyWithImpl(this._self, this._then);
final _CreateFrequentPlaceRequestModel _self;
final $Res Function(_CreateFrequentPlaceRequestModel) _then;
/// Create a copy of CreateFrequentPlaceRequestModel
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = null,Object? lat = null,Object? lng = null,Object? wifiList = null,Object? userId = freezed,Object? delegationId = freezed,Object? groupId = freezed,Object? deviceId = freezed,}) {
return _then(_CreateFrequentPlaceRequestModel(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String,lat: null == lat ? _self.lat : lat // ignore: cast_nullable_to_non_nullable
as double,lng: null == lng ? _self.lng : lng // ignore: cast_nullable_to_non_nullable
as double,wifiList: null == wifiList ? _self._wifiList : wifiList // ignore: cast_nullable_to_non_nullable
as List<WifiInfoResponseModel>,userId: freezed == userId ? _self.userId : userId // ignore: cast_nullable_to_non_nullable
as String?,delegationId: freezed == delegationId ? _self.delegationId : delegationId // ignore: cast_nullable_to_non_nullable
as String?,groupId: freezed == groupId ? _self.groupId : groupId // ignore: cast_nullable_to_non_nullable
as String?,deviceId: freezed == deviceId ? _self.deviceId : deviceId // ignore: cast_nullable_to_non_nullable
as String?,
));
}
}
// dart format on

View File

@@ -0,0 +1,41 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'create_frequent_place_request_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_CreateFrequentPlaceRequestModel _$CreateFrequentPlaceRequestModelFromJson(
Map<String, dynamic> json,
) => _CreateFrequentPlaceRequestModel(
id: json['id'] as String,
name: json['name'] as String,
lat: (json['lat'] as num).toDouble(),
lng: (json['lng'] as num).toDouble(),
wifiList:
(json['wifiList'] as List<dynamic>?)
?.map(
(e) => WifiInfoResponseModel.fromJson(e as Map<String, dynamic>),
)
.toList() ??
const [],
userId: json['userId'] as String?,
delegationId: json['delegationId'] as String?,
groupId: json['groupId'] as String?,
deviceId: json['deviceId'] as String?,
);
Map<String, dynamic> _$CreateFrequentPlaceRequestModelToJson(
_CreateFrequentPlaceRequestModel instance,
) => <String, dynamic>{
'id': instance.id,
'name': instance.name,
'lat': instance.lat,
'lng': instance.lng,
'wifiList': instance.wifiList,
'userId': instance.userId,
'delegationId': instance.delegationId,
'groupId': instance.groupId,
'deviceId': instance.deviceId,
};

View File

@@ -0,0 +1,24 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:location/src/core/data/models/frequent_places_response_model.dart';
import 'package:location/src/core/domain/entities/frequent_place_entity.dart';
part 'create_frequent_place_response_model.freezed.dart';
part 'create_frequent_place_response_model.g.dart';
@freezed
abstract class CreateFrequentPlaceResponseModel
with _$CreateFrequentPlaceResponseModel {
const factory CreateFrequentPlaceResponseModel({
required bool isCreated,
required FrequentPlaceItemResponseModel item,
}) = _CreateFrequentPlaceResponseModel;
factory CreateFrequentPlaceResponseModel.fromJson(
Map<String, dynamic> json) =>
_$CreateFrequentPlaceResponseModelFromJson(json);
}
extension CreateFrequentPlaceResponseModelMapper
on CreateFrequentPlaceResponseModel {
FrequentPlaceEntity toEntity() => item.toEntity();
}

View File

@@ -0,0 +1,298 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// coverage:ignore-file
// 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 'create_frequent_place_response_model.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$CreateFrequentPlaceResponseModel {
bool get isCreated; FrequentPlaceItemResponseModel get item;
/// Create a copy of CreateFrequentPlaceResponseModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$CreateFrequentPlaceResponseModelCopyWith<CreateFrequentPlaceResponseModel> get copyWith => _$CreateFrequentPlaceResponseModelCopyWithImpl<CreateFrequentPlaceResponseModel>(this as CreateFrequentPlaceResponseModel, _$identity);
/// Serializes this CreateFrequentPlaceResponseModel to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is CreateFrequentPlaceResponseModel&&(identical(other.isCreated, isCreated) || other.isCreated == isCreated)&&(identical(other.item, item) || other.item == item));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,isCreated,item);
@override
String toString() {
return 'CreateFrequentPlaceResponseModel(isCreated: $isCreated, item: $item)';
}
}
/// @nodoc
abstract mixin class $CreateFrequentPlaceResponseModelCopyWith<$Res> {
factory $CreateFrequentPlaceResponseModelCopyWith(CreateFrequentPlaceResponseModel value, $Res Function(CreateFrequentPlaceResponseModel) _then) = _$CreateFrequentPlaceResponseModelCopyWithImpl;
@useResult
$Res call({
bool isCreated, FrequentPlaceItemResponseModel item
});
$FrequentPlaceItemResponseModelCopyWith<$Res> get item;
}
/// @nodoc
class _$CreateFrequentPlaceResponseModelCopyWithImpl<$Res>
implements $CreateFrequentPlaceResponseModelCopyWith<$Res> {
_$CreateFrequentPlaceResponseModelCopyWithImpl(this._self, this._then);
final CreateFrequentPlaceResponseModel _self;
final $Res Function(CreateFrequentPlaceResponseModel) _then;
/// Create a copy of CreateFrequentPlaceResponseModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? isCreated = null,Object? item = null,}) {
return _then(_self.copyWith(
isCreated: null == isCreated ? _self.isCreated : isCreated // ignore: cast_nullable_to_non_nullable
as bool,item: null == item ? _self.item : item // ignore: cast_nullable_to_non_nullable
as FrequentPlaceItemResponseModel,
));
}
/// Create a copy of CreateFrequentPlaceResponseModel
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$FrequentPlaceItemResponseModelCopyWith<$Res> get item {
return $FrequentPlaceItemResponseModelCopyWith<$Res>(_self.item, (value) {
return _then(_self.copyWith(item: value));
});
}
}
/// Adds pattern-matching-related methods to [CreateFrequentPlaceResponseModel].
extension CreateFrequentPlaceResponseModelPatterns on CreateFrequentPlaceResponseModel {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _CreateFrequentPlaceResponseModel value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _CreateFrequentPlaceResponseModel() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _CreateFrequentPlaceResponseModel value) $default,){
final _that = this;
switch (_that) {
case _CreateFrequentPlaceResponseModel():
return $default(_that);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _CreateFrequentPlaceResponseModel value)? $default,){
final _that = this;
switch (_that) {
case _CreateFrequentPlaceResponseModel() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( bool isCreated, FrequentPlaceItemResponseModel item)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _CreateFrequentPlaceResponseModel() when $default != null:
return $default(_that.isCreated,_that.item);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( bool isCreated, FrequentPlaceItemResponseModel item) $default,) {final _that = this;
switch (_that) {
case _CreateFrequentPlaceResponseModel():
return $default(_that.isCreated,_that.item);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( bool isCreated, FrequentPlaceItemResponseModel item)? $default,) {final _that = this;
switch (_that) {
case _CreateFrequentPlaceResponseModel() when $default != null:
return $default(_that.isCreated,_that.item);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _CreateFrequentPlaceResponseModel implements CreateFrequentPlaceResponseModel {
const _CreateFrequentPlaceResponseModel({required this.isCreated, required this.item});
factory _CreateFrequentPlaceResponseModel.fromJson(Map<String, dynamic> json) => _$CreateFrequentPlaceResponseModelFromJson(json);
@override final bool isCreated;
@override final FrequentPlaceItemResponseModel item;
/// Create a copy of CreateFrequentPlaceResponseModel
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$CreateFrequentPlaceResponseModelCopyWith<_CreateFrequentPlaceResponseModel> get copyWith => __$CreateFrequentPlaceResponseModelCopyWithImpl<_CreateFrequentPlaceResponseModel>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$CreateFrequentPlaceResponseModelToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _CreateFrequentPlaceResponseModel&&(identical(other.isCreated, isCreated) || other.isCreated == isCreated)&&(identical(other.item, item) || other.item == item));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,isCreated,item);
@override
String toString() {
return 'CreateFrequentPlaceResponseModel(isCreated: $isCreated, item: $item)';
}
}
/// @nodoc
abstract mixin class _$CreateFrequentPlaceResponseModelCopyWith<$Res> implements $CreateFrequentPlaceResponseModelCopyWith<$Res> {
factory _$CreateFrequentPlaceResponseModelCopyWith(_CreateFrequentPlaceResponseModel value, $Res Function(_CreateFrequentPlaceResponseModel) _then) = __$CreateFrequentPlaceResponseModelCopyWithImpl;
@override @useResult
$Res call({
bool isCreated, FrequentPlaceItemResponseModel item
});
@override $FrequentPlaceItemResponseModelCopyWith<$Res> get item;
}
/// @nodoc
class __$CreateFrequentPlaceResponseModelCopyWithImpl<$Res>
implements _$CreateFrequentPlaceResponseModelCopyWith<$Res> {
__$CreateFrequentPlaceResponseModelCopyWithImpl(this._self, this._then);
final _CreateFrequentPlaceResponseModel _self;
final $Res Function(_CreateFrequentPlaceResponseModel) _then;
/// Create a copy of CreateFrequentPlaceResponseModel
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? isCreated = null,Object? item = null,}) {
return _then(_CreateFrequentPlaceResponseModel(
isCreated: null == isCreated ? _self.isCreated : isCreated // ignore: cast_nullable_to_non_nullable
as bool,item: null == item ? _self.item : item // ignore: cast_nullable_to_non_nullable
as FrequentPlaceItemResponseModel,
));
}
/// Create a copy of CreateFrequentPlaceResponseModel
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$FrequentPlaceItemResponseModelCopyWith<$Res> get item {
return $FrequentPlaceItemResponseModelCopyWith<$Res>(_self.item, (value) {
return _then(_self.copyWith(item: value));
});
}
}
// dart format on

View File

@@ -0,0 +1,20 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'create_frequent_place_response_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_CreateFrequentPlaceResponseModel _$CreateFrequentPlaceResponseModelFromJson(
Map<String, dynamic> json,
) => _CreateFrequentPlaceResponseModel(
isCreated: json['isCreated'] as bool,
item: FrequentPlaceItemResponseModel.fromJson(
json['item'] as Map<String, dynamic>,
),
);
Map<String, dynamic> _$CreateFrequentPlaceResponseModelToJson(
_CreateFrequentPlaceResponseModel instance,
) => <String, dynamic>{'isCreated': instance.isCreated, 'item': instance.item};

View File

@@ -0,0 +1,23 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'create_geofence_request_model.freezed.dart';
part 'create_geofence_request_model.g.dart';
@freezed
abstract class CreateGeofenceRequestModel with _$CreateGeofenceRequestModel {
const factory CreateGeofenceRequestModel({
required String id,
required String name,
String? description,
required double latitude,
required double longitude,
required double radius,
String? userId,
String? delegationId,
String? groupId,
String? deviceId,
}) = _CreateGeofenceRequestModel;
factory CreateGeofenceRequestModel.fromJson(Map<String, dynamic> json) =>
_$CreateGeofenceRequestModelFromJson(json);
}

View File

@@ -0,0 +1,304 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// coverage:ignore-file
// 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 'create_geofence_request_model.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$CreateGeofenceRequestModel {
String get id; String get name; String? get description; double get latitude; double get longitude; double get radius; String? get userId; String? get delegationId; String? get groupId; String? get deviceId;
/// Create a copy of CreateGeofenceRequestModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$CreateGeofenceRequestModelCopyWith<CreateGeofenceRequestModel> get copyWith => _$CreateGeofenceRequestModelCopyWithImpl<CreateGeofenceRequestModel>(this as CreateGeofenceRequestModel, _$identity);
/// Serializes this CreateGeofenceRequestModel to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is CreateGeofenceRequestModel&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&(identical(other.latitude, latitude) || other.latitude == latitude)&&(identical(other.longitude, longitude) || other.longitude == longitude)&&(identical(other.radius, radius) || other.radius == radius)&&(identical(other.userId, userId) || other.userId == userId)&&(identical(other.delegationId, delegationId) || other.delegationId == delegationId)&&(identical(other.groupId, groupId) || other.groupId == groupId)&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,name,description,latitude,longitude,radius,userId,delegationId,groupId,deviceId);
@override
String toString() {
return 'CreateGeofenceRequestModel(id: $id, name: $name, description: $description, latitude: $latitude, longitude: $longitude, radius: $radius, userId: $userId, delegationId: $delegationId, groupId: $groupId, deviceId: $deviceId)';
}
}
/// @nodoc
abstract mixin class $CreateGeofenceRequestModelCopyWith<$Res> {
factory $CreateGeofenceRequestModelCopyWith(CreateGeofenceRequestModel value, $Res Function(CreateGeofenceRequestModel) _then) = _$CreateGeofenceRequestModelCopyWithImpl;
@useResult
$Res call({
String id, String name, String? description, double latitude, double longitude, double radius, String? userId, String? delegationId, String? groupId, String? deviceId
});
}
/// @nodoc
class _$CreateGeofenceRequestModelCopyWithImpl<$Res>
implements $CreateGeofenceRequestModelCopyWith<$Res> {
_$CreateGeofenceRequestModelCopyWithImpl(this._self, this._then);
final CreateGeofenceRequestModel _self;
final $Res Function(CreateGeofenceRequestModel) _then;
/// Create a copy of CreateGeofenceRequestModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = null,Object? description = freezed,Object? latitude = null,Object? longitude = null,Object? radius = null,Object? userId = freezed,Object? delegationId = freezed,Object? groupId = freezed,Object? deviceId = freezed,}) {
return _then(_self.copyWith(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
as String?,latitude: null == latitude ? _self.latitude : latitude // ignore: cast_nullable_to_non_nullable
as double,longitude: null == longitude ? _self.longitude : longitude // ignore: cast_nullable_to_non_nullable
as double,radius: null == radius ? _self.radius : radius // ignore: cast_nullable_to_non_nullable
as double,userId: freezed == userId ? _self.userId : userId // ignore: cast_nullable_to_non_nullable
as String?,delegationId: freezed == delegationId ? _self.delegationId : delegationId // ignore: cast_nullable_to_non_nullable
as String?,groupId: freezed == groupId ? _self.groupId : groupId // ignore: cast_nullable_to_non_nullable
as String?,deviceId: freezed == deviceId ? _self.deviceId : deviceId // ignore: cast_nullable_to_non_nullable
as String?,
));
}
}
/// Adds pattern-matching-related methods to [CreateGeofenceRequestModel].
extension CreateGeofenceRequestModelPatterns on CreateGeofenceRequestModel {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _CreateGeofenceRequestModel value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _CreateGeofenceRequestModel() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _CreateGeofenceRequestModel value) $default,){
final _that = this;
switch (_that) {
case _CreateGeofenceRequestModel():
return $default(_that);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _CreateGeofenceRequestModel value)? $default,){
final _that = this;
switch (_that) {
case _CreateGeofenceRequestModel() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String name, String? description, double latitude, double longitude, double radius, String? userId, String? delegationId, String? groupId, String? deviceId)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _CreateGeofenceRequestModel() when $default != null:
return $default(_that.id,_that.name,_that.description,_that.latitude,_that.longitude,_that.radius,_that.userId,_that.delegationId,_that.groupId,_that.deviceId);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String name, String? description, double latitude, double longitude, double radius, String? userId, String? delegationId, String? groupId, String? deviceId) $default,) {final _that = this;
switch (_that) {
case _CreateGeofenceRequestModel():
return $default(_that.id,_that.name,_that.description,_that.latitude,_that.longitude,_that.radius,_that.userId,_that.delegationId,_that.groupId,_that.deviceId);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String name, String? description, double latitude, double longitude, double radius, String? userId, String? delegationId, String? groupId, String? deviceId)? $default,) {final _that = this;
switch (_that) {
case _CreateGeofenceRequestModel() when $default != null:
return $default(_that.id,_that.name,_that.description,_that.latitude,_that.longitude,_that.radius,_that.userId,_that.delegationId,_that.groupId,_that.deviceId);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _CreateGeofenceRequestModel implements CreateGeofenceRequestModel {
const _CreateGeofenceRequestModel({required this.id, required this.name, this.description, required this.latitude, required this.longitude, required this.radius, this.userId, this.delegationId, this.groupId, this.deviceId});
factory _CreateGeofenceRequestModel.fromJson(Map<String, dynamic> json) => _$CreateGeofenceRequestModelFromJson(json);
@override final String id;
@override final String name;
@override final String? description;
@override final double latitude;
@override final double longitude;
@override final double radius;
@override final String? userId;
@override final String? delegationId;
@override final String? groupId;
@override final String? deviceId;
/// Create a copy of CreateGeofenceRequestModel
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$CreateGeofenceRequestModelCopyWith<_CreateGeofenceRequestModel> get copyWith => __$CreateGeofenceRequestModelCopyWithImpl<_CreateGeofenceRequestModel>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$CreateGeofenceRequestModelToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _CreateGeofenceRequestModel&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&(identical(other.latitude, latitude) || other.latitude == latitude)&&(identical(other.longitude, longitude) || other.longitude == longitude)&&(identical(other.radius, radius) || other.radius == radius)&&(identical(other.userId, userId) || other.userId == userId)&&(identical(other.delegationId, delegationId) || other.delegationId == delegationId)&&(identical(other.groupId, groupId) || other.groupId == groupId)&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,name,description,latitude,longitude,radius,userId,delegationId,groupId,deviceId);
@override
String toString() {
return 'CreateGeofenceRequestModel(id: $id, name: $name, description: $description, latitude: $latitude, longitude: $longitude, radius: $radius, userId: $userId, delegationId: $delegationId, groupId: $groupId, deviceId: $deviceId)';
}
}
/// @nodoc
abstract mixin class _$CreateGeofenceRequestModelCopyWith<$Res> implements $CreateGeofenceRequestModelCopyWith<$Res> {
factory _$CreateGeofenceRequestModelCopyWith(_CreateGeofenceRequestModel value, $Res Function(_CreateGeofenceRequestModel) _then) = __$CreateGeofenceRequestModelCopyWithImpl;
@override @useResult
$Res call({
String id, String name, String? description, double latitude, double longitude, double radius, String? userId, String? delegationId, String? groupId, String? deviceId
});
}
/// @nodoc
class __$CreateGeofenceRequestModelCopyWithImpl<$Res>
implements _$CreateGeofenceRequestModelCopyWith<$Res> {
__$CreateGeofenceRequestModelCopyWithImpl(this._self, this._then);
final _CreateGeofenceRequestModel _self;
final $Res Function(_CreateGeofenceRequestModel) _then;
/// Create a copy of CreateGeofenceRequestModel
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = null,Object? description = freezed,Object? latitude = null,Object? longitude = null,Object? radius = null,Object? userId = freezed,Object? delegationId = freezed,Object? groupId = freezed,Object? deviceId = freezed,}) {
return _then(_CreateGeofenceRequestModel(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
as String?,latitude: null == latitude ? _self.latitude : latitude // ignore: cast_nullable_to_non_nullable
as double,longitude: null == longitude ? _self.longitude : longitude // ignore: cast_nullable_to_non_nullable
as double,radius: null == radius ? _self.radius : radius // ignore: cast_nullable_to_non_nullable
as double,userId: freezed == userId ? _self.userId : userId // ignore: cast_nullable_to_non_nullable
as String?,delegationId: freezed == delegationId ? _self.delegationId : delegationId // ignore: cast_nullable_to_non_nullable
as String?,groupId: freezed == groupId ? _self.groupId : groupId // ignore: cast_nullable_to_non_nullable
as String?,deviceId: freezed == deviceId ? _self.deviceId : deviceId // ignore: cast_nullable_to_non_nullable
as String?,
));
}
}
// dart format on

View File

@@ -0,0 +1,37 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'create_geofence_request_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_CreateGeofenceRequestModel _$CreateGeofenceRequestModelFromJson(
Map<String, dynamic> json,
) => _CreateGeofenceRequestModel(
id: json['id'] as String,
name: json['name'] as String,
description: json['description'] as String?,
latitude: (json['latitude'] as num).toDouble(),
longitude: (json['longitude'] as num).toDouble(),
radius: (json['radius'] as num).toDouble(),
userId: json['userId'] as String?,
delegationId: json['delegationId'] as String?,
groupId: json['groupId'] as String?,
deviceId: json['deviceId'] as String?,
);
Map<String, dynamic> _$CreateGeofenceRequestModelToJson(
_CreateGeofenceRequestModel instance,
) => <String, dynamic>{
'id': instance.id,
'name': instance.name,
'description': instance.description,
'latitude': instance.latitude,
'longitude': instance.longitude,
'radius': instance.radius,
'userId': instance.userId,
'delegationId': instance.delegationId,
'groupId': instance.groupId,
'deviceId': instance.deviceId,
};

View File

@@ -0,0 +1,34 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:location/src/core/data/models/geofences_response_model.dart';
import 'package:location/src/core/domain/entities/geofence_entity.dart';
part 'create_geofence_response_model.freezed.dart';
part 'create_geofence_response_model.g.dart';
@freezed
abstract class CreateGeofenceResponseModel with _$CreateGeofenceResponseModel {
const factory CreateGeofenceResponseModel({
required bool isCreated,
required GeofenceItemResponseModel item,
}) = _CreateGeofenceResponseModel;
factory CreateGeofenceResponseModel.fromJson(Map<String, dynamic> json) =>
_$CreateGeofenceResponseModelFromJson(json);
}
extension CreateGeofenceResponseModelMapper on CreateGeofenceResponseModel {
GeofenceEntity toEntity() {
return GeofenceEntity(
id: item.id,
name: item.name,
description: item.description,
latitude: item.latitude,
longitude: item.longitude,
radius: item.radius,
isActive: item.isActive,
deviceId: item.deviceId,
createdAt: item.createdAt,
updatedAt: item.updatedAt,
);
}
}

View File

@@ -0,0 +1,298 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// coverage:ignore-file
// 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 'create_geofence_response_model.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$CreateGeofenceResponseModel {
bool get isCreated; GeofenceItemResponseModel get item;
/// Create a copy of CreateGeofenceResponseModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$CreateGeofenceResponseModelCopyWith<CreateGeofenceResponseModel> get copyWith => _$CreateGeofenceResponseModelCopyWithImpl<CreateGeofenceResponseModel>(this as CreateGeofenceResponseModel, _$identity);
/// Serializes this CreateGeofenceResponseModel to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is CreateGeofenceResponseModel&&(identical(other.isCreated, isCreated) || other.isCreated == isCreated)&&(identical(other.item, item) || other.item == item));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,isCreated,item);
@override
String toString() {
return 'CreateGeofenceResponseModel(isCreated: $isCreated, item: $item)';
}
}
/// @nodoc
abstract mixin class $CreateGeofenceResponseModelCopyWith<$Res> {
factory $CreateGeofenceResponseModelCopyWith(CreateGeofenceResponseModel value, $Res Function(CreateGeofenceResponseModel) _then) = _$CreateGeofenceResponseModelCopyWithImpl;
@useResult
$Res call({
bool isCreated, GeofenceItemResponseModel item
});
$GeofenceItemResponseModelCopyWith<$Res> get item;
}
/// @nodoc
class _$CreateGeofenceResponseModelCopyWithImpl<$Res>
implements $CreateGeofenceResponseModelCopyWith<$Res> {
_$CreateGeofenceResponseModelCopyWithImpl(this._self, this._then);
final CreateGeofenceResponseModel _self;
final $Res Function(CreateGeofenceResponseModel) _then;
/// Create a copy of CreateGeofenceResponseModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? isCreated = null,Object? item = null,}) {
return _then(_self.copyWith(
isCreated: null == isCreated ? _self.isCreated : isCreated // ignore: cast_nullable_to_non_nullable
as bool,item: null == item ? _self.item : item // ignore: cast_nullable_to_non_nullable
as GeofenceItemResponseModel,
));
}
/// Create a copy of CreateGeofenceResponseModel
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$GeofenceItemResponseModelCopyWith<$Res> get item {
return $GeofenceItemResponseModelCopyWith<$Res>(_self.item, (value) {
return _then(_self.copyWith(item: value));
});
}
}
/// Adds pattern-matching-related methods to [CreateGeofenceResponseModel].
extension CreateGeofenceResponseModelPatterns on CreateGeofenceResponseModel {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _CreateGeofenceResponseModel value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _CreateGeofenceResponseModel() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _CreateGeofenceResponseModel value) $default,){
final _that = this;
switch (_that) {
case _CreateGeofenceResponseModel():
return $default(_that);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _CreateGeofenceResponseModel value)? $default,){
final _that = this;
switch (_that) {
case _CreateGeofenceResponseModel() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( bool isCreated, GeofenceItemResponseModel item)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _CreateGeofenceResponseModel() when $default != null:
return $default(_that.isCreated,_that.item);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( bool isCreated, GeofenceItemResponseModel item) $default,) {final _that = this;
switch (_that) {
case _CreateGeofenceResponseModel():
return $default(_that.isCreated,_that.item);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( bool isCreated, GeofenceItemResponseModel item)? $default,) {final _that = this;
switch (_that) {
case _CreateGeofenceResponseModel() when $default != null:
return $default(_that.isCreated,_that.item);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _CreateGeofenceResponseModel implements CreateGeofenceResponseModel {
const _CreateGeofenceResponseModel({required this.isCreated, required this.item});
factory _CreateGeofenceResponseModel.fromJson(Map<String, dynamic> json) => _$CreateGeofenceResponseModelFromJson(json);
@override final bool isCreated;
@override final GeofenceItemResponseModel item;
/// Create a copy of CreateGeofenceResponseModel
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$CreateGeofenceResponseModelCopyWith<_CreateGeofenceResponseModel> get copyWith => __$CreateGeofenceResponseModelCopyWithImpl<_CreateGeofenceResponseModel>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$CreateGeofenceResponseModelToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _CreateGeofenceResponseModel&&(identical(other.isCreated, isCreated) || other.isCreated == isCreated)&&(identical(other.item, item) || other.item == item));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,isCreated,item);
@override
String toString() {
return 'CreateGeofenceResponseModel(isCreated: $isCreated, item: $item)';
}
}
/// @nodoc
abstract mixin class _$CreateGeofenceResponseModelCopyWith<$Res> implements $CreateGeofenceResponseModelCopyWith<$Res> {
factory _$CreateGeofenceResponseModelCopyWith(_CreateGeofenceResponseModel value, $Res Function(_CreateGeofenceResponseModel) _then) = __$CreateGeofenceResponseModelCopyWithImpl;
@override @useResult
$Res call({
bool isCreated, GeofenceItemResponseModel item
});
@override $GeofenceItemResponseModelCopyWith<$Res> get item;
}
/// @nodoc
class __$CreateGeofenceResponseModelCopyWithImpl<$Res>
implements _$CreateGeofenceResponseModelCopyWith<$Res> {
__$CreateGeofenceResponseModelCopyWithImpl(this._self, this._then);
final _CreateGeofenceResponseModel _self;
final $Res Function(_CreateGeofenceResponseModel) _then;
/// Create a copy of CreateGeofenceResponseModel
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? isCreated = null,Object? item = null,}) {
return _then(_CreateGeofenceResponseModel(
isCreated: null == isCreated ? _self.isCreated : isCreated // ignore: cast_nullable_to_non_nullable
as bool,item: null == item ? _self.item : item // ignore: cast_nullable_to_non_nullable
as GeofenceItemResponseModel,
));
}
/// Create a copy of CreateGeofenceResponseModel
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$GeofenceItemResponseModelCopyWith<$Res> get item {
return $GeofenceItemResponseModelCopyWith<$Res>(_self.item, (value) {
return _then(_self.copyWith(item: value));
});
}
}
// dart format on

View File

@@ -0,0 +1,20 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'create_geofence_response_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_CreateGeofenceResponseModel _$CreateGeofenceResponseModelFromJson(
Map<String, dynamic> json,
) => _CreateGeofenceResponseModel(
isCreated: json['isCreated'] as bool,
item: GeofenceItemResponseModel.fromJson(
json['item'] as Map<String, dynamic>,
),
);
Map<String, dynamic> _$CreateGeofenceResponseModelToJson(
_CreateGeofenceResponseModel instance,
) => <String, dynamic>{'isCreated': instance.isCreated, 'item': instance.item};

View File

@@ -0,0 +1,81 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:location/src/core/domain/entities/frequent_place_entity.dart';
part 'frequent_places_response_model.freezed.dart';
part 'frequent_places_response_model.g.dart';
@freezed
abstract class FrequentPlacesResponseModel with _$FrequentPlacesResponseModel {
const factory FrequentPlacesResponseModel({
required List<FrequentPlaceItemResponseModel> items,
int? total,
int? page,
int? pages,
}) = _FrequentPlacesResponseModel;
factory FrequentPlacesResponseModel.fromJson(Map<String, dynamic> json) =>
_$FrequentPlacesResponseModelFromJson(json);
}
@freezed
abstract class FrequentPlaceItemResponseModel
with _$FrequentPlaceItemResponseModel {
const factory FrequentPlaceItemResponseModel({
required String id,
required String name,
String? userId,
String? delegationId,
String? groupId,
String? deviceId,
required double lat,
required double lng,
@Default([]) List<WifiInfoResponseModel> wifiList,
required int createdAt,
int? updatedAt,
}) = _FrequentPlaceItemResponseModel;
factory FrequentPlaceItemResponseModel.fromJson(Map<String, dynamic> json) =>
_$FrequentPlaceItemResponseModelFromJson(json);
}
@freezed
abstract class WifiInfoResponseModel with _$WifiInfoResponseModel {
const factory WifiInfoResponseModel({
required String SSID,
required String BSSID,
required String signal,
}) = _WifiInfoResponseModel;
factory WifiInfoResponseModel.fromJson(Map<String, dynamic> json) =>
_$WifiInfoResponseModelFromJson(json);
}
extension FrequentPlacesResponseModelMapper on FrequentPlacesResponseModel {
List<FrequentPlaceEntity> toEntity() {
return items.map((item) => item.toEntity()).toList();
}
}
extension FrequentPlaceItemResponseModelMapper
on FrequentPlaceItemResponseModel {
FrequentPlaceEntity toEntity() {
return FrequentPlaceEntity(
id: id,
name: name,
lat: lat,
lng: lng,
wifiList: wifiList
.map(
(w) => WifiInfoEntity(
ssid: w.SSID,
bssid: w.BSSID,
signal: w.signal,
),
)
.toList(),
deviceId: deviceId,
createdAt: createdAt,
updatedAt: updatedAt,
);
}
}

View File

@@ -0,0 +1,860 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// coverage:ignore-file
// 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 'frequent_places_response_model.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$FrequentPlacesResponseModel {
List<FrequentPlaceItemResponseModel> get items; int? get total; int? get page; int? get pages;
/// Create a copy of FrequentPlacesResponseModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$FrequentPlacesResponseModelCopyWith<FrequentPlacesResponseModel> get copyWith => _$FrequentPlacesResponseModelCopyWithImpl<FrequentPlacesResponseModel>(this as FrequentPlacesResponseModel, _$identity);
/// Serializes this FrequentPlacesResponseModel to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is FrequentPlacesResponseModel&&const DeepCollectionEquality().equals(other.items, items)&&(identical(other.total, total) || other.total == total)&&(identical(other.page, page) || other.page == page)&&(identical(other.pages, pages) || other.pages == pages));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(items),total,page,pages);
@override
String toString() {
return 'FrequentPlacesResponseModel(items: $items, total: $total, page: $page, pages: $pages)';
}
}
/// @nodoc
abstract mixin class $FrequentPlacesResponseModelCopyWith<$Res> {
factory $FrequentPlacesResponseModelCopyWith(FrequentPlacesResponseModel value, $Res Function(FrequentPlacesResponseModel) _then) = _$FrequentPlacesResponseModelCopyWithImpl;
@useResult
$Res call({
List<FrequentPlaceItemResponseModel> items, int? total, int? page, int? pages
});
}
/// @nodoc
class _$FrequentPlacesResponseModelCopyWithImpl<$Res>
implements $FrequentPlacesResponseModelCopyWith<$Res> {
_$FrequentPlacesResponseModelCopyWithImpl(this._self, this._then);
final FrequentPlacesResponseModel _self;
final $Res Function(FrequentPlacesResponseModel) _then;
/// Create a copy of FrequentPlacesResponseModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? items = null,Object? total = freezed,Object? page = freezed,Object? pages = freezed,}) {
return _then(_self.copyWith(
items: null == items ? _self.items : items // ignore: cast_nullable_to_non_nullable
as List<FrequentPlaceItemResponseModel>,total: freezed == total ? _self.total : total // ignore: cast_nullable_to_non_nullable
as int?,page: freezed == page ? _self.page : page // ignore: cast_nullable_to_non_nullable
as int?,pages: freezed == pages ? _self.pages : pages // ignore: cast_nullable_to_non_nullable
as int?,
));
}
}
/// Adds pattern-matching-related methods to [FrequentPlacesResponseModel].
extension FrequentPlacesResponseModelPatterns on FrequentPlacesResponseModel {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _FrequentPlacesResponseModel value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _FrequentPlacesResponseModel() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _FrequentPlacesResponseModel value) $default,){
final _that = this;
switch (_that) {
case _FrequentPlacesResponseModel():
return $default(_that);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _FrequentPlacesResponseModel value)? $default,){
final _that = this;
switch (_that) {
case _FrequentPlacesResponseModel() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( List<FrequentPlaceItemResponseModel> items, int? total, int? page, int? pages)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _FrequentPlacesResponseModel() when $default != null:
return $default(_that.items,_that.total,_that.page,_that.pages);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( List<FrequentPlaceItemResponseModel> items, int? total, int? page, int? pages) $default,) {final _that = this;
switch (_that) {
case _FrequentPlacesResponseModel():
return $default(_that.items,_that.total,_that.page,_that.pages);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( List<FrequentPlaceItemResponseModel> items, int? total, int? page, int? pages)? $default,) {final _that = this;
switch (_that) {
case _FrequentPlacesResponseModel() when $default != null:
return $default(_that.items,_that.total,_that.page,_that.pages);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _FrequentPlacesResponseModel implements FrequentPlacesResponseModel {
const _FrequentPlacesResponseModel({required final List<FrequentPlaceItemResponseModel> items, this.total, this.page, this.pages}): _items = items;
factory _FrequentPlacesResponseModel.fromJson(Map<String, dynamic> json) => _$FrequentPlacesResponseModelFromJson(json);
final List<FrequentPlaceItemResponseModel> _items;
@override List<FrequentPlaceItemResponseModel> get items {
if (_items is EqualUnmodifiableListView) return _items;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_items);
}
@override final int? total;
@override final int? page;
@override final int? pages;
/// Create a copy of FrequentPlacesResponseModel
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$FrequentPlacesResponseModelCopyWith<_FrequentPlacesResponseModel> get copyWith => __$FrequentPlacesResponseModelCopyWithImpl<_FrequentPlacesResponseModel>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$FrequentPlacesResponseModelToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _FrequentPlacesResponseModel&&const DeepCollectionEquality().equals(other._items, _items)&&(identical(other.total, total) || other.total == total)&&(identical(other.page, page) || other.page == page)&&(identical(other.pages, pages) || other.pages == pages));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_items),total,page,pages);
@override
String toString() {
return 'FrequentPlacesResponseModel(items: $items, total: $total, page: $page, pages: $pages)';
}
}
/// @nodoc
abstract mixin class _$FrequentPlacesResponseModelCopyWith<$Res> implements $FrequentPlacesResponseModelCopyWith<$Res> {
factory _$FrequentPlacesResponseModelCopyWith(_FrequentPlacesResponseModel value, $Res Function(_FrequentPlacesResponseModel) _then) = __$FrequentPlacesResponseModelCopyWithImpl;
@override @useResult
$Res call({
List<FrequentPlaceItemResponseModel> items, int? total, int? page, int? pages
});
}
/// @nodoc
class __$FrequentPlacesResponseModelCopyWithImpl<$Res>
implements _$FrequentPlacesResponseModelCopyWith<$Res> {
__$FrequentPlacesResponseModelCopyWithImpl(this._self, this._then);
final _FrequentPlacesResponseModel _self;
final $Res Function(_FrequentPlacesResponseModel) _then;
/// Create a copy of FrequentPlacesResponseModel
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? items = null,Object? total = freezed,Object? page = freezed,Object? pages = freezed,}) {
return _then(_FrequentPlacesResponseModel(
items: null == items ? _self._items : items // ignore: cast_nullable_to_non_nullable
as List<FrequentPlaceItemResponseModel>,total: freezed == total ? _self.total : total // ignore: cast_nullable_to_non_nullable
as int?,page: freezed == page ? _self.page : page // ignore: cast_nullable_to_non_nullable
as int?,pages: freezed == pages ? _self.pages : pages // ignore: cast_nullable_to_non_nullable
as int?,
));
}
}
/// @nodoc
mixin _$FrequentPlaceItemResponseModel {
String get id; String get name; String? get userId; String? get delegationId; String? get groupId; String? get deviceId; double get lat; double get lng; List<WifiInfoResponseModel> get wifiList; int get createdAt; int? get updatedAt;
/// Create a copy of FrequentPlaceItemResponseModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$FrequentPlaceItemResponseModelCopyWith<FrequentPlaceItemResponseModel> get copyWith => _$FrequentPlaceItemResponseModelCopyWithImpl<FrequentPlaceItemResponseModel>(this as FrequentPlaceItemResponseModel, _$identity);
/// Serializes this FrequentPlaceItemResponseModel to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is FrequentPlaceItemResponseModel&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.userId, userId) || other.userId == userId)&&(identical(other.delegationId, delegationId) || other.delegationId == delegationId)&&(identical(other.groupId, groupId) || other.groupId == groupId)&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId)&&(identical(other.lat, lat) || other.lat == lat)&&(identical(other.lng, lng) || other.lng == lng)&&const DeepCollectionEquality().equals(other.wifiList, wifiList)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,name,userId,delegationId,groupId,deviceId,lat,lng,const DeepCollectionEquality().hash(wifiList),createdAt,updatedAt);
@override
String toString() {
return 'FrequentPlaceItemResponseModel(id: $id, name: $name, userId: $userId, delegationId: $delegationId, groupId: $groupId, deviceId: $deviceId, lat: $lat, lng: $lng, wifiList: $wifiList, createdAt: $createdAt, updatedAt: $updatedAt)';
}
}
/// @nodoc
abstract mixin class $FrequentPlaceItemResponseModelCopyWith<$Res> {
factory $FrequentPlaceItemResponseModelCopyWith(FrequentPlaceItemResponseModel value, $Res Function(FrequentPlaceItemResponseModel) _then) = _$FrequentPlaceItemResponseModelCopyWithImpl;
@useResult
$Res call({
String id, String name, String? userId, String? delegationId, String? groupId, String? deviceId, double lat, double lng, List<WifiInfoResponseModel> wifiList, int createdAt, int? updatedAt
});
}
/// @nodoc
class _$FrequentPlaceItemResponseModelCopyWithImpl<$Res>
implements $FrequentPlaceItemResponseModelCopyWith<$Res> {
_$FrequentPlaceItemResponseModelCopyWithImpl(this._self, this._then);
final FrequentPlaceItemResponseModel _self;
final $Res Function(FrequentPlaceItemResponseModel) _then;
/// Create a copy of FrequentPlaceItemResponseModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = null,Object? userId = freezed,Object? delegationId = freezed,Object? groupId = freezed,Object? deviceId = freezed,Object? lat = null,Object? lng = null,Object? wifiList = null,Object? createdAt = null,Object? updatedAt = freezed,}) {
return _then(_self.copyWith(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String,userId: freezed == userId ? _self.userId : userId // ignore: cast_nullable_to_non_nullable
as String?,delegationId: freezed == delegationId ? _self.delegationId : delegationId // ignore: cast_nullable_to_non_nullable
as String?,groupId: freezed == groupId ? _self.groupId : groupId // ignore: cast_nullable_to_non_nullable
as String?,deviceId: freezed == deviceId ? _self.deviceId : deviceId // ignore: cast_nullable_to_non_nullable
as String?,lat: null == lat ? _self.lat : lat // ignore: cast_nullable_to_non_nullable
as double,lng: null == lng ? _self.lng : lng // ignore: cast_nullable_to_non_nullable
as double,wifiList: null == wifiList ? _self.wifiList : wifiList // ignore: cast_nullable_to_non_nullable
as List<WifiInfoResponseModel>,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
as int,updatedAt: freezed == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
as int?,
));
}
}
/// Adds pattern-matching-related methods to [FrequentPlaceItemResponseModel].
extension FrequentPlaceItemResponseModelPatterns on FrequentPlaceItemResponseModel {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _FrequentPlaceItemResponseModel value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _FrequentPlaceItemResponseModel() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _FrequentPlaceItemResponseModel value) $default,){
final _that = this;
switch (_that) {
case _FrequentPlaceItemResponseModel():
return $default(_that);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _FrequentPlaceItemResponseModel value)? $default,){
final _that = this;
switch (_that) {
case _FrequentPlaceItemResponseModel() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String name, String? userId, String? delegationId, String? groupId, String? deviceId, double lat, double lng, List<WifiInfoResponseModel> wifiList, int createdAt, int? updatedAt)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _FrequentPlaceItemResponseModel() when $default != null:
return $default(_that.id,_that.name,_that.userId,_that.delegationId,_that.groupId,_that.deviceId,_that.lat,_that.lng,_that.wifiList,_that.createdAt,_that.updatedAt);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String name, String? userId, String? delegationId, String? groupId, String? deviceId, double lat, double lng, List<WifiInfoResponseModel> wifiList, int createdAt, int? updatedAt) $default,) {final _that = this;
switch (_that) {
case _FrequentPlaceItemResponseModel():
return $default(_that.id,_that.name,_that.userId,_that.delegationId,_that.groupId,_that.deviceId,_that.lat,_that.lng,_that.wifiList,_that.createdAt,_that.updatedAt);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String name, String? userId, String? delegationId, String? groupId, String? deviceId, double lat, double lng, List<WifiInfoResponseModel> wifiList, int createdAt, int? updatedAt)? $default,) {final _that = this;
switch (_that) {
case _FrequentPlaceItemResponseModel() when $default != null:
return $default(_that.id,_that.name,_that.userId,_that.delegationId,_that.groupId,_that.deviceId,_that.lat,_that.lng,_that.wifiList,_that.createdAt,_that.updatedAt);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _FrequentPlaceItemResponseModel implements FrequentPlaceItemResponseModel {
const _FrequentPlaceItemResponseModel({required this.id, required this.name, this.userId, this.delegationId, this.groupId, this.deviceId, required this.lat, required this.lng, final List<WifiInfoResponseModel> wifiList = const [], required this.createdAt, this.updatedAt}): _wifiList = wifiList;
factory _FrequentPlaceItemResponseModel.fromJson(Map<String, dynamic> json) => _$FrequentPlaceItemResponseModelFromJson(json);
@override final String id;
@override final String name;
@override final String? userId;
@override final String? delegationId;
@override final String? groupId;
@override final String? deviceId;
@override final double lat;
@override final double lng;
final List<WifiInfoResponseModel> _wifiList;
@override@JsonKey() List<WifiInfoResponseModel> get wifiList {
if (_wifiList is EqualUnmodifiableListView) return _wifiList;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_wifiList);
}
@override final int createdAt;
@override final int? updatedAt;
/// Create a copy of FrequentPlaceItemResponseModel
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$FrequentPlaceItemResponseModelCopyWith<_FrequentPlaceItemResponseModel> get copyWith => __$FrequentPlaceItemResponseModelCopyWithImpl<_FrequentPlaceItemResponseModel>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$FrequentPlaceItemResponseModelToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _FrequentPlaceItemResponseModel&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.userId, userId) || other.userId == userId)&&(identical(other.delegationId, delegationId) || other.delegationId == delegationId)&&(identical(other.groupId, groupId) || other.groupId == groupId)&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId)&&(identical(other.lat, lat) || other.lat == lat)&&(identical(other.lng, lng) || other.lng == lng)&&const DeepCollectionEquality().equals(other._wifiList, _wifiList)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,name,userId,delegationId,groupId,deviceId,lat,lng,const DeepCollectionEquality().hash(_wifiList),createdAt,updatedAt);
@override
String toString() {
return 'FrequentPlaceItemResponseModel(id: $id, name: $name, userId: $userId, delegationId: $delegationId, groupId: $groupId, deviceId: $deviceId, lat: $lat, lng: $lng, wifiList: $wifiList, createdAt: $createdAt, updatedAt: $updatedAt)';
}
}
/// @nodoc
abstract mixin class _$FrequentPlaceItemResponseModelCopyWith<$Res> implements $FrequentPlaceItemResponseModelCopyWith<$Res> {
factory _$FrequentPlaceItemResponseModelCopyWith(_FrequentPlaceItemResponseModel value, $Res Function(_FrequentPlaceItemResponseModel) _then) = __$FrequentPlaceItemResponseModelCopyWithImpl;
@override @useResult
$Res call({
String id, String name, String? userId, String? delegationId, String? groupId, String? deviceId, double lat, double lng, List<WifiInfoResponseModel> wifiList, int createdAt, int? updatedAt
});
}
/// @nodoc
class __$FrequentPlaceItemResponseModelCopyWithImpl<$Res>
implements _$FrequentPlaceItemResponseModelCopyWith<$Res> {
__$FrequentPlaceItemResponseModelCopyWithImpl(this._self, this._then);
final _FrequentPlaceItemResponseModel _self;
final $Res Function(_FrequentPlaceItemResponseModel) _then;
/// Create a copy of FrequentPlaceItemResponseModel
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = null,Object? userId = freezed,Object? delegationId = freezed,Object? groupId = freezed,Object? deviceId = freezed,Object? lat = null,Object? lng = null,Object? wifiList = null,Object? createdAt = null,Object? updatedAt = freezed,}) {
return _then(_FrequentPlaceItemResponseModel(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String,userId: freezed == userId ? _self.userId : userId // ignore: cast_nullable_to_non_nullable
as String?,delegationId: freezed == delegationId ? _self.delegationId : delegationId // ignore: cast_nullable_to_non_nullable
as String?,groupId: freezed == groupId ? _self.groupId : groupId // ignore: cast_nullable_to_non_nullable
as String?,deviceId: freezed == deviceId ? _self.deviceId : deviceId // ignore: cast_nullable_to_non_nullable
as String?,lat: null == lat ? _self.lat : lat // ignore: cast_nullable_to_non_nullable
as double,lng: null == lng ? _self.lng : lng // ignore: cast_nullable_to_non_nullable
as double,wifiList: null == wifiList ? _self._wifiList : wifiList // ignore: cast_nullable_to_non_nullable
as List<WifiInfoResponseModel>,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
as int,updatedAt: freezed == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
as int?,
));
}
}
/// @nodoc
mixin _$WifiInfoResponseModel {
String get SSID; String get BSSID; String get signal;
/// Create a copy of WifiInfoResponseModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$WifiInfoResponseModelCopyWith<WifiInfoResponseModel> get copyWith => _$WifiInfoResponseModelCopyWithImpl<WifiInfoResponseModel>(this as WifiInfoResponseModel, _$identity);
/// Serializes this WifiInfoResponseModel to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is WifiInfoResponseModel&&(identical(other.SSID, SSID) || other.SSID == SSID)&&(identical(other.BSSID, BSSID) || other.BSSID == BSSID)&&(identical(other.signal, signal) || other.signal == signal));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,SSID,BSSID,signal);
@override
String toString() {
return 'WifiInfoResponseModel(SSID: $SSID, BSSID: $BSSID, signal: $signal)';
}
}
/// @nodoc
abstract mixin class $WifiInfoResponseModelCopyWith<$Res> {
factory $WifiInfoResponseModelCopyWith(WifiInfoResponseModel value, $Res Function(WifiInfoResponseModel) _then) = _$WifiInfoResponseModelCopyWithImpl;
@useResult
$Res call({
String SSID, String BSSID, String signal
});
}
/// @nodoc
class _$WifiInfoResponseModelCopyWithImpl<$Res>
implements $WifiInfoResponseModelCopyWith<$Res> {
_$WifiInfoResponseModelCopyWithImpl(this._self, this._then);
final WifiInfoResponseModel _self;
final $Res Function(WifiInfoResponseModel) _then;
/// Create a copy of WifiInfoResponseModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? SSID = null,Object? BSSID = null,Object? signal = null,}) {
return _then(_self.copyWith(
SSID: null == SSID ? _self.SSID : SSID // ignore: cast_nullable_to_non_nullable
as String,BSSID: null == BSSID ? _self.BSSID : BSSID // ignore: cast_nullable_to_non_nullable
as String,signal: null == signal ? _self.signal : signal // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
/// Adds pattern-matching-related methods to [WifiInfoResponseModel].
extension WifiInfoResponseModelPatterns on WifiInfoResponseModel {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _WifiInfoResponseModel value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _WifiInfoResponseModel() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _WifiInfoResponseModel value) $default,){
final _that = this;
switch (_that) {
case _WifiInfoResponseModel():
return $default(_that);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _WifiInfoResponseModel value)? $default,){
final _that = this;
switch (_that) {
case _WifiInfoResponseModel() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String SSID, String BSSID, String signal)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _WifiInfoResponseModel() when $default != null:
return $default(_that.SSID,_that.BSSID,_that.signal);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String SSID, String BSSID, String signal) $default,) {final _that = this;
switch (_that) {
case _WifiInfoResponseModel():
return $default(_that.SSID,_that.BSSID,_that.signal);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String SSID, String BSSID, String signal)? $default,) {final _that = this;
switch (_that) {
case _WifiInfoResponseModel() when $default != null:
return $default(_that.SSID,_that.BSSID,_that.signal);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _WifiInfoResponseModel implements WifiInfoResponseModel {
const _WifiInfoResponseModel({required this.SSID, required this.BSSID, required this.signal});
factory _WifiInfoResponseModel.fromJson(Map<String, dynamic> json) => _$WifiInfoResponseModelFromJson(json);
@override final String SSID;
@override final String BSSID;
@override final String signal;
/// Create a copy of WifiInfoResponseModel
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$WifiInfoResponseModelCopyWith<_WifiInfoResponseModel> get copyWith => __$WifiInfoResponseModelCopyWithImpl<_WifiInfoResponseModel>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$WifiInfoResponseModelToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _WifiInfoResponseModel&&(identical(other.SSID, SSID) || other.SSID == SSID)&&(identical(other.BSSID, BSSID) || other.BSSID == BSSID)&&(identical(other.signal, signal) || other.signal == signal));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,SSID,BSSID,signal);
@override
String toString() {
return 'WifiInfoResponseModel(SSID: $SSID, BSSID: $BSSID, signal: $signal)';
}
}
/// @nodoc
abstract mixin class _$WifiInfoResponseModelCopyWith<$Res> implements $WifiInfoResponseModelCopyWith<$Res> {
factory _$WifiInfoResponseModelCopyWith(_WifiInfoResponseModel value, $Res Function(_WifiInfoResponseModel) _then) = __$WifiInfoResponseModelCopyWithImpl;
@override @useResult
$Res call({
String SSID, String BSSID, String signal
});
}
/// @nodoc
class __$WifiInfoResponseModelCopyWithImpl<$Res>
implements _$WifiInfoResponseModelCopyWith<$Res> {
__$WifiInfoResponseModelCopyWithImpl(this._self, this._then);
final _WifiInfoResponseModel _self;
final $Res Function(_WifiInfoResponseModel) _then;
/// Create a copy of WifiInfoResponseModel
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? SSID = null,Object? BSSID = null,Object? signal = null,}) {
return _then(_WifiInfoResponseModel(
SSID: null == SSID ? _self.SSID : SSID // ignore: cast_nullable_to_non_nullable
as String,BSSID: null == BSSID ? _self.BSSID : BSSID // ignore: cast_nullable_to_non_nullable
as String,signal: null == signal ? _self.signal : signal // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
// dart format on

View File

@@ -0,0 +1,84 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'frequent_places_response_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_FrequentPlacesResponseModel _$FrequentPlacesResponseModelFromJson(
Map<String, dynamic> json,
) => _FrequentPlacesResponseModel(
items: (json['items'] as List<dynamic>)
.map(
(e) =>
FrequentPlaceItemResponseModel.fromJson(e as Map<String, dynamic>),
)
.toList(),
total: (json['total'] as num?)?.toInt(),
page: (json['page'] as num?)?.toInt(),
pages: (json['pages'] as num?)?.toInt(),
);
Map<String, dynamic> _$FrequentPlacesResponseModelToJson(
_FrequentPlacesResponseModel instance,
) => <String, dynamic>{
'items': instance.items,
'total': instance.total,
'page': instance.page,
'pages': instance.pages,
};
_FrequentPlaceItemResponseModel _$FrequentPlaceItemResponseModelFromJson(
Map<String, dynamic> json,
) => _FrequentPlaceItemResponseModel(
id: json['id'] as String,
name: json['name'] as String,
userId: json['userId'] as String?,
delegationId: json['delegationId'] as String?,
groupId: json['groupId'] as String?,
deviceId: json['deviceId'] as String?,
lat: (json['lat'] as num).toDouble(),
lng: (json['lng'] as num).toDouble(),
wifiList:
(json['wifiList'] as List<dynamic>?)
?.map(
(e) => WifiInfoResponseModel.fromJson(e as Map<String, dynamic>),
)
.toList() ??
const [],
createdAt: (json['createdAt'] as num).toInt(),
updatedAt: (json['updatedAt'] as num?)?.toInt(),
);
Map<String, dynamic> _$FrequentPlaceItemResponseModelToJson(
_FrequentPlaceItemResponseModel instance,
) => <String, dynamic>{
'id': instance.id,
'name': instance.name,
'userId': instance.userId,
'delegationId': instance.delegationId,
'groupId': instance.groupId,
'deviceId': instance.deviceId,
'lat': instance.lat,
'lng': instance.lng,
'wifiList': instance.wifiList,
'createdAt': instance.createdAt,
'updatedAt': instance.updatedAt,
};
_WifiInfoResponseModel _$WifiInfoResponseModelFromJson(
Map<String, dynamic> json,
) => _WifiInfoResponseModel(
SSID: json['SSID'] as String,
BSSID: json['BSSID'] as String,
signal: json['signal'] as String,
);
Map<String, dynamic> _$WifiInfoResponseModelToJson(
_WifiInfoResponseModel instance,
) => <String, dynamic>{
'SSID': instance.SSID,
'BSSID': instance.BSSID,
'signal': instance.signal,
};

View File

@@ -0,0 +1,61 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:location/src/core/domain/entities/geofence_entity.dart';
part 'geofences_response_model.freezed.dart';
part 'geofences_response_model.g.dart';
@freezed
abstract class GeofencesResponseModel with _$GeofencesResponseModel {
const factory GeofencesResponseModel({
required List<GeofenceItemResponseModel> items,
int? total,
int? page,
int? pages,
}) = _GeofencesResponseModel;
factory GeofencesResponseModel.fromJson(Map<String, dynamic> json) =>
_$GeofencesResponseModelFromJson(json);
}
@freezed
abstract class GeofenceItemResponseModel with _$GeofenceItemResponseModel {
const factory GeofenceItemResponseModel({
required String id,
required String name,
String? description,
required double latitude,
required double longitude,
required double radius,
String? userId,
String? delegationId,
String? groupId,
String? deviceId,
required bool isActive,
required int createdAt,
int? updatedAt,
}) = _GeofenceItemResponseModel;
factory GeofenceItemResponseModel.fromJson(Map<String, dynamic> json) =>
_$GeofenceItemResponseModelFromJson(json);
}
extension GeofencesResponseModelMapper on GeofencesResponseModel {
List<GeofenceEntity> toEntity() {
return items
.map(
(item) => GeofenceEntity(
id: item.id,
name: item.name,
description: item.description,
latitude: item.latitude,
longitude: item.longitude,
radius: item.radius,
isActive: item.isActive,
deviceId: item.deviceId,
createdAt: item.createdAt,
updatedAt: item.updatedAt,
),
)
.toList();
}
}

View File

@@ -0,0 +1,591 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// coverage:ignore-file
// 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 'geofences_response_model.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$GeofencesResponseModel {
List<GeofenceItemResponseModel> get items; int? get total; int? get page; int? get pages;
/// Create a copy of GeofencesResponseModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$GeofencesResponseModelCopyWith<GeofencesResponseModel> get copyWith => _$GeofencesResponseModelCopyWithImpl<GeofencesResponseModel>(this as GeofencesResponseModel, _$identity);
/// Serializes this GeofencesResponseModel to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is GeofencesResponseModel&&const DeepCollectionEquality().equals(other.items, items)&&(identical(other.total, total) || other.total == total)&&(identical(other.page, page) || other.page == page)&&(identical(other.pages, pages) || other.pages == pages));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(items),total,page,pages);
@override
String toString() {
return 'GeofencesResponseModel(items: $items, total: $total, page: $page, pages: $pages)';
}
}
/// @nodoc
abstract mixin class $GeofencesResponseModelCopyWith<$Res> {
factory $GeofencesResponseModelCopyWith(GeofencesResponseModel value, $Res Function(GeofencesResponseModel) _then) = _$GeofencesResponseModelCopyWithImpl;
@useResult
$Res call({
List<GeofenceItemResponseModel> items, int? total, int? page, int? pages
});
}
/// @nodoc
class _$GeofencesResponseModelCopyWithImpl<$Res>
implements $GeofencesResponseModelCopyWith<$Res> {
_$GeofencesResponseModelCopyWithImpl(this._self, this._then);
final GeofencesResponseModel _self;
final $Res Function(GeofencesResponseModel) _then;
/// Create a copy of GeofencesResponseModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? items = null,Object? total = freezed,Object? page = freezed,Object? pages = freezed,}) {
return _then(_self.copyWith(
items: null == items ? _self.items : items // ignore: cast_nullable_to_non_nullable
as List<GeofenceItemResponseModel>,total: freezed == total ? _self.total : total // ignore: cast_nullable_to_non_nullable
as int?,page: freezed == page ? _self.page : page // ignore: cast_nullable_to_non_nullable
as int?,pages: freezed == pages ? _self.pages : pages // ignore: cast_nullable_to_non_nullable
as int?,
));
}
}
/// Adds pattern-matching-related methods to [GeofencesResponseModel].
extension GeofencesResponseModelPatterns on GeofencesResponseModel {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _GeofencesResponseModel value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _GeofencesResponseModel() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _GeofencesResponseModel value) $default,){
final _that = this;
switch (_that) {
case _GeofencesResponseModel():
return $default(_that);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _GeofencesResponseModel value)? $default,){
final _that = this;
switch (_that) {
case _GeofencesResponseModel() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( List<GeofenceItemResponseModel> items, int? total, int? page, int? pages)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _GeofencesResponseModel() when $default != null:
return $default(_that.items,_that.total,_that.page,_that.pages);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( List<GeofenceItemResponseModel> items, int? total, int? page, int? pages) $default,) {final _that = this;
switch (_that) {
case _GeofencesResponseModel():
return $default(_that.items,_that.total,_that.page,_that.pages);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( List<GeofenceItemResponseModel> items, int? total, int? page, int? pages)? $default,) {final _that = this;
switch (_that) {
case _GeofencesResponseModel() when $default != null:
return $default(_that.items,_that.total,_that.page,_that.pages);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _GeofencesResponseModel implements GeofencesResponseModel {
const _GeofencesResponseModel({required final List<GeofenceItemResponseModel> items, this.total, this.page, this.pages}): _items = items;
factory _GeofencesResponseModel.fromJson(Map<String, dynamic> json) => _$GeofencesResponseModelFromJson(json);
final List<GeofenceItemResponseModel> _items;
@override List<GeofenceItemResponseModel> get items {
if (_items is EqualUnmodifiableListView) return _items;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_items);
}
@override final int? total;
@override final int? page;
@override final int? pages;
/// Create a copy of GeofencesResponseModel
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$GeofencesResponseModelCopyWith<_GeofencesResponseModel> get copyWith => __$GeofencesResponseModelCopyWithImpl<_GeofencesResponseModel>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$GeofencesResponseModelToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _GeofencesResponseModel&&const DeepCollectionEquality().equals(other._items, _items)&&(identical(other.total, total) || other.total == total)&&(identical(other.page, page) || other.page == page)&&(identical(other.pages, pages) || other.pages == pages));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_items),total,page,pages);
@override
String toString() {
return 'GeofencesResponseModel(items: $items, total: $total, page: $page, pages: $pages)';
}
}
/// @nodoc
abstract mixin class _$GeofencesResponseModelCopyWith<$Res> implements $GeofencesResponseModelCopyWith<$Res> {
factory _$GeofencesResponseModelCopyWith(_GeofencesResponseModel value, $Res Function(_GeofencesResponseModel) _then) = __$GeofencesResponseModelCopyWithImpl;
@override @useResult
$Res call({
List<GeofenceItemResponseModel> items, int? total, int? page, int? pages
});
}
/// @nodoc
class __$GeofencesResponseModelCopyWithImpl<$Res>
implements _$GeofencesResponseModelCopyWith<$Res> {
__$GeofencesResponseModelCopyWithImpl(this._self, this._then);
final _GeofencesResponseModel _self;
final $Res Function(_GeofencesResponseModel) _then;
/// Create a copy of GeofencesResponseModel
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? items = null,Object? total = freezed,Object? page = freezed,Object? pages = freezed,}) {
return _then(_GeofencesResponseModel(
items: null == items ? _self._items : items // ignore: cast_nullable_to_non_nullable
as List<GeofenceItemResponseModel>,total: freezed == total ? _self.total : total // ignore: cast_nullable_to_non_nullable
as int?,page: freezed == page ? _self.page : page // ignore: cast_nullable_to_non_nullable
as int?,pages: freezed == pages ? _self.pages : pages // ignore: cast_nullable_to_non_nullable
as int?,
));
}
}
/// @nodoc
mixin _$GeofenceItemResponseModel {
String get id; String get name; String? get description; double get latitude; double get longitude; double get radius; String? get userId; String? get delegationId; String? get groupId; String? get deviceId; bool get isActive; int get createdAt; int? get updatedAt;
/// Create a copy of GeofenceItemResponseModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$GeofenceItemResponseModelCopyWith<GeofenceItemResponseModel> get copyWith => _$GeofenceItemResponseModelCopyWithImpl<GeofenceItemResponseModel>(this as GeofenceItemResponseModel, _$identity);
/// Serializes this GeofenceItemResponseModel to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is GeofenceItemResponseModel&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&(identical(other.latitude, latitude) || other.latitude == latitude)&&(identical(other.longitude, longitude) || other.longitude == longitude)&&(identical(other.radius, radius) || other.radius == radius)&&(identical(other.userId, userId) || other.userId == userId)&&(identical(other.delegationId, delegationId) || other.delegationId == delegationId)&&(identical(other.groupId, groupId) || other.groupId == groupId)&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId)&&(identical(other.isActive, isActive) || other.isActive == isActive)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,name,description,latitude,longitude,radius,userId,delegationId,groupId,deviceId,isActive,createdAt,updatedAt);
@override
String toString() {
return 'GeofenceItemResponseModel(id: $id, name: $name, description: $description, latitude: $latitude, longitude: $longitude, radius: $radius, userId: $userId, delegationId: $delegationId, groupId: $groupId, deviceId: $deviceId, isActive: $isActive, createdAt: $createdAt, updatedAt: $updatedAt)';
}
}
/// @nodoc
abstract mixin class $GeofenceItemResponseModelCopyWith<$Res> {
factory $GeofenceItemResponseModelCopyWith(GeofenceItemResponseModel value, $Res Function(GeofenceItemResponseModel) _then) = _$GeofenceItemResponseModelCopyWithImpl;
@useResult
$Res call({
String id, String name, String? description, double latitude, double longitude, double radius, String? userId, String? delegationId, String? groupId, String? deviceId, bool isActive, int createdAt, int? updatedAt
});
}
/// @nodoc
class _$GeofenceItemResponseModelCopyWithImpl<$Res>
implements $GeofenceItemResponseModelCopyWith<$Res> {
_$GeofenceItemResponseModelCopyWithImpl(this._self, this._then);
final GeofenceItemResponseModel _self;
final $Res Function(GeofenceItemResponseModel) _then;
/// Create a copy of GeofenceItemResponseModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = null,Object? description = freezed,Object? latitude = null,Object? longitude = null,Object? radius = null,Object? userId = freezed,Object? delegationId = freezed,Object? groupId = freezed,Object? deviceId = freezed,Object? isActive = null,Object? createdAt = null,Object? updatedAt = freezed,}) {
return _then(_self.copyWith(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
as String?,latitude: null == latitude ? _self.latitude : latitude // ignore: cast_nullable_to_non_nullable
as double,longitude: null == longitude ? _self.longitude : longitude // ignore: cast_nullable_to_non_nullable
as double,radius: null == radius ? _self.radius : radius // ignore: cast_nullable_to_non_nullable
as double,userId: freezed == userId ? _self.userId : userId // ignore: cast_nullable_to_non_nullable
as String?,delegationId: freezed == delegationId ? _self.delegationId : delegationId // ignore: cast_nullable_to_non_nullable
as String?,groupId: freezed == groupId ? _self.groupId : groupId // ignore: cast_nullable_to_non_nullable
as String?,deviceId: freezed == deviceId ? _self.deviceId : deviceId // ignore: cast_nullable_to_non_nullable
as String?,isActive: null == isActive ? _self.isActive : isActive // ignore: cast_nullable_to_non_nullable
as bool,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
as int,updatedAt: freezed == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
as int?,
));
}
}
/// Adds pattern-matching-related methods to [GeofenceItemResponseModel].
extension GeofenceItemResponseModelPatterns on GeofenceItemResponseModel {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _GeofenceItemResponseModel value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _GeofenceItemResponseModel() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _GeofenceItemResponseModel value) $default,){
final _that = this;
switch (_that) {
case _GeofenceItemResponseModel():
return $default(_that);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _GeofenceItemResponseModel value)? $default,){
final _that = this;
switch (_that) {
case _GeofenceItemResponseModel() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String name, String? description, double latitude, double longitude, double radius, String? userId, String? delegationId, String? groupId, String? deviceId, bool isActive, int createdAt, int? updatedAt)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _GeofenceItemResponseModel() when $default != null:
return $default(_that.id,_that.name,_that.description,_that.latitude,_that.longitude,_that.radius,_that.userId,_that.delegationId,_that.groupId,_that.deviceId,_that.isActive,_that.createdAt,_that.updatedAt);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String name, String? description, double latitude, double longitude, double radius, String? userId, String? delegationId, String? groupId, String? deviceId, bool isActive, int createdAt, int? updatedAt) $default,) {final _that = this;
switch (_that) {
case _GeofenceItemResponseModel():
return $default(_that.id,_that.name,_that.description,_that.latitude,_that.longitude,_that.radius,_that.userId,_that.delegationId,_that.groupId,_that.deviceId,_that.isActive,_that.createdAt,_that.updatedAt);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String name, String? description, double latitude, double longitude, double radius, String? userId, String? delegationId, String? groupId, String? deviceId, bool isActive, int createdAt, int? updatedAt)? $default,) {final _that = this;
switch (_that) {
case _GeofenceItemResponseModel() when $default != null:
return $default(_that.id,_that.name,_that.description,_that.latitude,_that.longitude,_that.radius,_that.userId,_that.delegationId,_that.groupId,_that.deviceId,_that.isActive,_that.createdAt,_that.updatedAt);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _GeofenceItemResponseModel implements GeofenceItemResponseModel {
const _GeofenceItemResponseModel({required this.id, required this.name, this.description, required this.latitude, required this.longitude, required this.radius, this.userId, this.delegationId, this.groupId, this.deviceId, required this.isActive, required this.createdAt, this.updatedAt});
factory _GeofenceItemResponseModel.fromJson(Map<String, dynamic> json) => _$GeofenceItemResponseModelFromJson(json);
@override final String id;
@override final String name;
@override final String? description;
@override final double latitude;
@override final double longitude;
@override final double radius;
@override final String? userId;
@override final String? delegationId;
@override final String? groupId;
@override final String? deviceId;
@override final bool isActive;
@override final int createdAt;
@override final int? updatedAt;
/// Create a copy of GeofenceItemResponseModel
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$GeofenceItemResponseModelCopyWith<_GeofenceItemResponseModel> get copyWith => __$GeofenceItemResponseModelCopyWithImpl<_GeofenceItemResponseModel>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$GeofenceItemResponseModelToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _GeofenceItemResponseModel&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&(identical(other.latitude, latitude) || other.latitude == latitude)&&(identical(other.longitude, longitude) || other.longitude == longitude)&&(identical(other.radius, radius) || other.radius == radius)&&(identical(other.userId, userId) || other.userId == userId)&&(identical(other.delegationId, delegationId) || other.delegationId == delegationId)&&(identical(other.groupId, groupId) || other.groupId == groupId)&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId)&&(identical(other.isActive, isActive) || other.isActive == isActive)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,name,description,latitude,longitude,radius,userId,delegationId,groupId,deviceId,isActive,createdAt,updatedAt);
@override
String toString() {
return 'GeofenceItemResponseModel(id: $id, name: $name, description: $description, latitude: $latitude, longitude: $longitude, radius: $radius, userId: $userId, delegationId: $delegationId, groupId: $groupId, deviceId: $deviceId, isActive: $isActive, createdAt: $createdAt, updatedAt: $updatedAt)';
}
}
/// @nodoc
abstract mixin class _$GeofenceItemResponseModelCopyWith<$Res> implements $GeofenceItemResponseModelCopyWith<$Res> {
factory _$GeofenceItemResponseModelCopyWith(_GeofenceItemResponseModel value, $Res Function(_GeofenceItemResponseModel) _then) = __$GeofenceItemResponseModelCopyWithImpl;
@override @useResult
$Res call({
String id, String name, String? description, double latitude, double longitude, double radius, String? userId, String? delegationId, String? groupId, String? deviceId, bool isActive, int createdAt, int? updatedAt
});
}
/// @nodoc
class __$GeofenceItemResponseModelCopyWithImpl<$Res>
implements _$GeofenceItemResponseModelCopyWith<$Res> {
__$GeofenceItemResponseModelCopyWithImpl(this._self, this._then);
final _GeofenceItemResponseModel _self;
final $Res Function(_GeofenceItemResponseModel) _then;
/// Create a copy of GeofenceItemResponseModel
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = null,Object? description = freezed,Object? latitude = null,Object? longitude = null,Object? radius = null,Object? userId = freezed,Object? delegationId = freezed,Object? groupId = freezed,Object? deviceId = freezed,Object? isActive = null,Object? createdAt = null,Object? updatedAt = freezed,}) {
return _then(_GeofenceItemResponseModel(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
as String?,latitude: null == latitude ? _self.latitude : latitude // ignore: cast_nullable_to_non_nullable
as double,longitude: null == longitude ? _self.longitude : longitude // ignore: cast_nullable_to_non_nullable
as double,radius: null == radius ? _self.radius : radius // ignore: cast_nullable_to_non_nullable
as double,userId: freezed == userId ? _self.userId : userId // ignore: cast_nullable_to_non_nullable
as String?,delegationId: freezed == delegationId ? _self.delegationId : delegationId // ignore: cast_nullable_to_non_nullable
as String?,groupId: freezed == groupId ? _self.groupId : groupId // ignore: cast_nullable_to_non_nullable
as String?,deviceId: freezed == deviceId ? _self.deviceId : deviceId // ignore: cast_nullable_to_non_nullable
as String?,isActive: null == isActive ? _self.isActive : isActive // ignore: cast_nullable_to_non_nullable
as bool,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
as int,updatedAt: freezed == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
as int?,
));
}
}
// dart format on

View File

@@ -0,0 +1,63 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'geofences_response_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_GeofencesResponseModel _$GeofencesResponseModelFromJson(
Map<String, dynamic> json,
) => _GeofencesResponseModel(
items: (json['items'] as List<dynamic>)
.map((e) => GeofenceItemResponseModel.fromJson(e as Map<String, dynamic>))
.toList(),
total: (json['total'] as num?)?.toInt(),
page: (json['page'] as num?)?.toInt(),
pages: (json['pages'] as num?)?.toInt(),
);
Map<String, dynamic> _$GeofencesResponseModelToJson(
_GeofencesResponseModel instance,
) => <String, dynamic>{
'items': instance.items,
'total': instance.total,
'page': instance.page,
'pages': instance.pages,
};
_GeofenceItemResponseModel _$GeofenceItemResponseModelFromJson(
Map<String, dynamic> json,
) => _GeofenceItemResponseModel(
id: json['id'] as String,
name: json['name'] as String,
description: json['description'] as String?,
latitude: (json['latitude'] as num).toDouble(),
longitude: (json['longitude'] as num).toDouble(),
radius: (json['radius'] as num).toDouble(),
userId: json['userId'] as String?,
delegationId: json['delegationId'] as String?,
groupId: json['groupId'] as String?,
deviceId: json['deviceId'] as String?,
isActive: json['isActive'] as bool,
createdAt: (json['createdAt'] as num).toInt(),
updatedAt: (json['updatedAt'] as num?)?.toInt(),
);
Map<String, dynamic> _$GeofenceItemResponseModelToJson(
_GeofenceItemResponseModel instance,
) => <String, dynamic>{
'id': instance.id,
'name': instance.name,
'description': instance.description,
'latitude': instance.latitude,
'longitude': instance.longitude,
'radius': instance.radius,
'userId': instance.userId,
'delegationId': instance.delegationId,
'groupId': instance.groupId,
'deviceId': instance.deviceId,
'isActive': instance.isActive,
'createdAt': instance.createdAt,
'updatedAt': instance.updatedAt,
};

View File

@@ -0,0 +1,25 @@
import 'package:control_panel/control_panel.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'position_history_response_model.freezed.dart';
part 'position_history_response_model.g.dart';
@freezed
abstract class PositionHistoryResponseModel
with _$PositionHistoryResponseModel {
const factory PositionHistoryResponseModel({
required List<LatestPositionsItemResponseModel> items,
required int total,
required int page,
required int pages,
}) = _PositionHistoryResponseModel;
factory PositionHistoryResponseModel.fromJson(Map<String, dynamic> json) =>
_$PositionHistoryResponseModelFromJson(json);
}
extension PositionHistoryResponseModelMapper on PositionHistoryResponseModel {
List<PositionEntity> toEntity() {
return LatestPositionsResponseModel(items: items).toEntity();
}
}

View File

@@ -0,0 +1,292 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// coverage:ignore-file
// 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 'position_history_response_model.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$PositionHistoryResponseModel {
List<LatestPositionsItemResponseModel> get items; int get total; int get page; int get pages;
/// Create a copy of PositionHistoryResponseModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$PositionHistoryResponseModelCopyWith<PositionHistoryResponseModel> get copyWith => _$PositionHistoryResponseModelCopyWithImpl<PositionHistoryResponseModel>(this as PositionHistoryResponseModel, _$identity);
/// Serializes this PositionHistoryResponseModel to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is PositionHistoryResponseModel&&const DeepCollectionEquality().equals(other.items, items)&&(identical(other.total, total) || other.total == total)&&(identical(other.page, page) || other.page == page)&&(identical(other.pages, pages) || other.pages == pages));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(items),total,page,pages);
@override
String toString() {
return 'PositionHistoryResponseModel(items: $items, total: $total, page: $page, pages: $pages)';
}
}
/// @nodoc
abstract mixin class $PositionHistoryResponseModelCopyWith<$Res> {
factory $PositionHistoryResponseModelCopyWith(PositionHistoryResponseModel value, $Res Function(PositionHistoryResponseModel) _then) = _$PositionHistoryResponseModelCopyWithImpl;
@useResult
$Res call({
List<LatestPositionsItemResponseModel> items, int total, int page, int pages
});
}
/// @nodoc
class _$PositionHistoryResponseModelCopyWithImpl<$Res>
implements $PositionHistoryResponseModelCopyWith<$Res> {
_$PositionHistoryResponseModelCopyWithImpl(this._self, this._then);
final PositionHistoryResponseModel _self;
final $Res Function(PositionHistoryResponseModel) _then;
/// Create a copy of PositionHistoryResponseModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? items = null,Object? total = null,Object? page = null,Object? pages = null,}) {
return _then(_self.copyWith(
items: null == items ? _self.items : items // ignore: cast_nullable_to_non_nullable
as List<LatestPositionsItemResponseModel>,total: null == total ? _self.total : total // ignore: cast_nullable_to_non_nullable
as int,page: null == page ? _self.page : page // ignore: cast_nullable_to_non_nullable
as int,pages: null == pages ? _self.pages : pages // ignore: cast_nullable_to_non_nullable
as int,
));
}
}
/// Adds pattern-matching-related methods to [PositionHistoryResponseModel].
extension PositionHistoryResponseModelPatterns on PositionHistoryResponseModel {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _PositionHistoryResponseModel value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _PositionHistoryResponseModel() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _PositionHistoryResponseModel value) $default,){
final _that = this;
switch (_that) {
case _PositionHistoryResponseModel():
return $default(_that);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _PositionHistoryResponseModel value)? $default,){
final _that = this;
switch (_that) {
case _PositionHistoryResponseModel() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( List<LatestPositionsItemResponseModel> items, int total, int page, int pages)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _PositionHistoryResponseModel() when $default != null:
return $default(_that.items,_that.total,_that.page,_that.pages);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( List<LatestPositionsItemResponseModel> items, int total, int page, int pages) $default,) {final _that = this;
switch (_that) {
case _PositionHistoryResponseModel():
return $default(_that.items,_that.total,_that.page,_that.pages);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( List<LatestPositionsItemResponseModel> items, int total, int page, int pages)? $default,) {final _that = this;
switch (_that) {
case _PositionHistoryResponseModel() when $default != null:
return $default(_that.items,_that.total,_that.page,_that.pages);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _PositionHistoryResponseModel implements PositionHistoryResponseModel {
const _PositionHistoryResponseModel({required final List<LatestPositionsItemResponseModel> items, required this.total, required this.page, required this.pages}): _items = items;
factory _PositionHistoryResponseModel.fromJson(Map<String, dynamic> json) => _$PositionHistoryResponseModelFromJson(json);
final List<LatestPositionsItemResponseModel> _items;
@override List<LatestPositionsItemResponseModel> get items {
if (_items is EqualUnmodifiableListView) return _items;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_items);
}
@override final int total;
@override final int page;
@override final int pages;
/// Create a copy of PositionHistoryResponseModel
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$PositionHistoryResponseModelCopyWith<_PositionHistoryResponseModel> get copyWith => __$PositionHistoryResponseModelCopyWithImpl<_PositionHistoryResponseModel>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$PositionHistoryResponseModelToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _PositionHistoryResponseModel&&const DeepCollectionEquality().equals(other._items, _items)&&(identical(other.total, total) || other.total == total)&&(identical(other.page, page) || other.page == page)&&(identical(other.pages, pages) || other.pages == pages));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_items),total,page,pages);
@override
String toString() {
return 'PositionHistoryResponseModel(items: $items, total: $total, page: $page, pages: $pages)';
}
}
/// @nodoc
abstract mixin class _$PositionHistoryResponseModelCopyWith<$Res> implements $PositionHistoryResponseModelCopyWith<$Res> {
factory _$PositionHistoryResponseModelCopyWith(_PositionHistoryResponseModel value, $Res Function(_PositionHistoryResponseModel) _then) = __$PositionHistoryResponseModelCopyWithImpl;
@override @useResult
$Res call({
List<LatestPositionsItemResponseModel> items, int total, int page, int pages
});
}
/// @nodoc
class __$PositionHistoryResponseModelCopyWithImpl<$Res>
implements _$PositionHistoryResponseModelCopyWith<$Res> {
__$PositionHistoryResponseModelCopyWithImpl(this._self, this._then);
final _PositionHistoryResponseModel _self;
final $Res Function(_PositionHistoryResponseModel) _then;
/// Create a copy of PositionHistoryResponseModel
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? items = null,Object? total = null,Object? page = null,Object? pages = null,}) {
return _then(_PositionHistoryResponseModel(
items: null == items ? _self._items : items // ignore: cast_nullable_to_non_nullable
as List<LatestPositionsItemResponseModel>,total: null == total ? _self.total : total // ignore: cast_nullable_to_non_nullable
as int,page: null == page ? _self.page : page // ignore: cast_nullable_to_non_nullable
as int,pages: null == pages ? _self.pages : pages // ignore: cast_nullable_to_non_nullable
as int,
));
}
}
// dart format on

View File

@@ -0,0 +1,31 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'position_history_response_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_PositionHistoryResponseModel _$PositionHistoryResponseModelFromJson(
Map<String, dynamic> json,
) => _PositionHistoryResponseModel(
items: (json['items'] as List<dynamic>)
.map(
(e) => LatestPositionsItemResponseModel.fromJson(
e as Map<String, dynamic>,
),
)
.toList(),
total: (json['total'] as num).toInt(),
page: (json['page'] as num).toInt(),
pages: (json['pages'] as num).toInt(),
);
Map<String, dynamic> _$PositionHistoryResponseModelToJson(
_PositionHistoryResponseModel instance,
) => <String, dynamic>{
'items': instance.items,
'total': instance.total,
'page': instance.page,
'pages': instance.pages,
};

View File

@@ -0,0 +1,21 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:location/src/core/data/models/frequent_places_response_model.dart';
part 'update_frequent_place_request_model.freezed.dart';
part 'update_frequent_place_request_model.g.dart';
@freezed
abstract class UpdateFrequentPlaceRequestModel
with _$UpdateFrequentPlaceRequestModel {
const factory UpdateFrequentPlaceRequestModel({
required String id,
required String name,
required double lat,
required double lng,
@Default([]) List<WifiInfoResponseModel> wifiList,
}) = _UpdateFrequentPlaceRequestModel;
factory UpdateFrequentPlaceRequestModel.fromJson(
Map<String, dynamic> json) =>
_$UpdateFrequentPlaceRequestModelFromJson(json);
}

View File

@@ -0,0 +1,295 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// coverage:ignore-file
// 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 'update_frequent_place_request_model.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$UpdateFrequentPlaceRequestModel {
String get id; String get name; double get lat; double get lng; List<WifiInfoResponseModel> get wifiList;
/// Create a copy of UpdateFrequentPlaceRequestModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$UpdateFrequentPlaceRequestModelCopyWith<UpdateFrequentPlaceRequestModel> get copyWith => _$UpdateFrequentPlaceRequestModelCopyWithImpl<UpdateFrequentPlaceRequestModel>(this as UpdateFrequentPlaceRequestModel, _$identity);
/// Serializes this UpdateFrequentPlaceRequestModel to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is UpdateFrequentPlaceRequestModel&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.lat, lat) || other.lat == lat)&&(identical(other.lng, lng) || other.lng == lng)&&const DeepCollectionEquality().equals(other.wifiList, wifiList));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,name,lat,lng,const DeepCollectionEquality().hash(wifiList));
@override
String toString() {
return 'UpdateFrequentPlaceRequestModel(id: $id, name: $name, lat: $lat, lng: $lng, wifiList: $wifiList)';
}
}
/// @nodoc
abstract mixin class $UpdateFrequentPlaceRequestModelCopyWith<$Res> {
factory $UpdateFrequentPlaceRequestModelCopyWith(UpdateFrequentPlaceRequestModel value, $Res Function(UpdateFrequentPlaceRequestModel) _then) = _$UpdateFrequentPlaceRequestModelCopyWithImpl;
@useResult
$Res call({
String id, String name, double lat, double lng, List<WifiInfoResponseModel> wifiList
});
}
/// @nodoc
class _$UpdateFrequentPlaceRequestModelCopyWithImpl<$Res>
implements $UpdateFrequentPlaceRequestModelCopyWith<$Res> {
_$UpdateFrequentPlaceRequestModelCopyWithImpl(this._self, this._then);
final UpdateFrequentPlaceRequestModel _self;
final $Res Function(UpdateFrequentPlaceRequestModel) _then;
/// Create a copy of UpdateFrequentPlaceRequestModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = null,Object? lat = null,Object? lng = null,Object? wifiList = null,}) {
return _then(_self.copyWith(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String,lat: null == lat ? _self.lat : lat // ignore: cast_nullable_to_non_nullable
as double,lng: null == lng ? _self.lng : lng // ignore: cast_nullable_to_non_nullable
as double,wifiList: null == wifiList ? _self.wifiList : wifiList // ignore: cast_nullable_to_non_nullable
as List<WifiInfoResponseModel>,
));
}
}
/// Adds pattern-matching-related methods to [UpdateFrequentPlaceRequestModel].
extension UpdateFrequentPlaceRequestModelPatterns on UpdateFrequentPlaceRequestModel {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _UpdateFrequentPlaceRequestModel value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _UpdateFrequentPlaceRequestModel() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _UpdateFrequentPlaceRequestModel value) $default,){
final _that = this;
switch (_that) {
case _UpdateFrequentPlaceRequestModel():
return $default(_that);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _UpdateFrequentPlaceRequestModel value)? $default,){
final _that = this;
switch (_that) {
case _UpdateFrequentPlaceRequestModel() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String name, double lat, double lng, List<WifiInfoResponseModel> wifiList)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _UpdateFrequentPlaceRequestModel() when $default != null:
return $default(_that.id,_that.name,_that.lat,_that.lng,_that.wifiList);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String name, double lat, double lng, List<WifiInfoResponseModel> wifiList) $default,) {final _that = this;
switch (_that) {
case _UpdateFrequentPlaceRequestModel():
return $default(_that.id,_that.name,_that.lat,_that.lng,_that.wifiList);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String name, double lat, double lng, List<WifiInfoResponseModel> wifiList)? $default,) {final _that = this;
switch (_that) {
case _UpdateFrequentPlaceRequestModel() when $default != null:
return $default(_that.id,_that.name,_that.lat,_that.lng,_that.wifiList);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _UpdateFrequentPlaceRequestModel implements UpdateFrequentPlaceRequestModel {
const _UpdateFrequentPlaceRequestModel({required this.id, required this.name, required this.lat, required this.lng, final List<WifiInfoResponseModel> wifiList = const []}): _wifiList = wifiList;
factory _UpdateFrequentPlaceRequestModel.fromJson(Map<String, dynamic> json) => _$UpdateFrequentPlaceRequestModelFromJson(json);
@override final String id;
@override final String name;
@override final double lat;
@override final double lng;
final List<WifiInfoResponseModel> _wifiList;
@override@JsonKey() List<WifiInfoResponseModel> get wifiList {
if (_wifiList is EqualUnmodifiableListView) return _wifiList;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_wifiList);
}
/// Create a copy of UpdateFrequentPlaceRequestModel
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$UpdateFrequentPlaceRequestModelCopyWith<_UpdateFrequentPlaceRequestModel> get copyWith => __$UpdateFrequentPlaceRequestModelCopyWithImpl<_UpdateFrequentPlaceRequestModel>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$UpdateFrequentPlaceRequestModelToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _UpdateFrequentPlaceRequestModel&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.lat, lat) || other.lat == lat)&&(identical(other.lng, lng) || other.lng == lng)&&const DeepCollectionEquality().equals(other._wifiList, _wifiList));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,name,lat,lng,const DeepCollectionEquality().hash(_wifiList));
@override
String toString() {
return 'UpdateFrequentPlaceRequestModel(id: $id, name: $name, lat: $lat, lng: $lng, wifiList: $wifiList)';
}
}
/// @nodoc
abstract mixin class _$UpdateFrequentPlaceRequestModelCopyWith<$Res> implements $UpdateFrequentPlaceRequestModelCopyWith<$Res> {
factory _$UpdateFrequentPlaceRequestModelCopyWith(_UpdateFrequentPlaceRequestModel value, $Res Function(_UpdateFrequentPlaceRequestModel) _then) = __$UpdateFrequentPlaceRequestModelCopyWithImpl;
@override @useResult
$Res call({
String id, String name, double lat, double lng, List<WifiInfoResponseModel> wifiList
});
}
/// @nodoc
class __$UpdateFrequentPlaceRequestModelCopyWithImpl<$Res>
implements _$UpdateFrequentPlaceRequestModelCopyWith<$Res> {
__$UpdateFrequentPlaceRequestModelCopyWithImpl(this._self, this._then);
final _UpdateFrequentPlaceRequestModel _self;
final $Res Function(_UpdateFrequentPlaceRequestModel) _then;
/// Create a copy of UpdateFrequentPlaceRequestModel
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = null,Object? lat = null,Object? lng = null,Object? wifiList = null,}) {
return _then(_UpdateFrequentPlaceRequestModel(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String,lat: null == lat ? _self.lat : lat // ignore: cast_nullable_to_non_nullable
as double,lng: null == lng ? _self.lng : lng // ignore: cast_nullable_to_non_nullable
as double,wifiList: null == wifiList ? _self._wifiList : wifiList // ignore: cast_nullable_to_non_nullable
as List<WifiInfoResponseModel>,
));
}
}
// dart format on

View File

@@ -0,0 +1,33 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'update_frequent_place_request_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_UpdateFrequentPlaceRequestModel _$UpdateFrequentPlaceRequestModelFromJson(
Map<String, dynamic> json,
) => _UpdateFrequentPlaceRequestModel(
id: json['id'] as String,
name: json['name'] as String,
lat: (json['lat'] as num).toDouble(),
lng: (json['lng'] as num).toDouble(),
wifiList:
(json['wifiList'] as List<dynamic>?)
?.map(
(e) => WifiInfoResponseModel.fromJson(e as Map<String, dynamic>),
)
.toList() ??
const [],
);
Map<String, dynamic> _$UpdateFrequentPlaceRequestModelToJson(
_UpdateFrequentPlaceRequestModel instance,
) => <String, dynamic>{
'id': instance.id,
'name': instance.name,
'lat': instance.lat,
'lng': instance.lng,
'wifiList': instance.wifiList,
};

View File

@@ -0,0 +1,24 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:location/src/core/data/models/frequent_places_response_model.dart';
import 'package:location/src/core/domain/entities/frequent_place_entity.dart';
part 'update_frequent_place_response_model.freezed.dart';
part 'update_frequent_place_response_model.g.dart';
@freezed
abstract class UpdateFrequentPlaceResponseModel
with _$UpdateFrequentPlaceResponseModel {
const factory UpdateFrequentPlaceResponseModel({
required bool isUpdated,
required FrequentPlaceItemResponseModel item,
}) = _UpdateFrequentPlaceResponseModel;
factory UpdateFrequentPlaceResponseModel.fromJson(
Map<String, dynamic> json) =>
_$UpdateFrequentPlaceResponseModelFromJson(json);
}
extension UpdateFrequentPlaceResponseModelMapper
on UpdateFrequentPlaceResponseModel {
FrequentPlaceEntity toEntity() => item.toEntity();
}

View File

@@ -0,0 +1,298 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// coverage:ignore-file
// 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 'update_frequent_place_response_model.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$UpdateFrequentPlaceResponseModel {
bool get isUpdated; FrequentPlaceItemResponseModel get item;
/// Create a copy of UpdateFrequentPlaceResponseModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$UpdateFrequentPlaceResponseModelCopyWith<UpdateFrequentPlaceResponseModel> get copyWith => _$UpdateFrequentPlaceResponseModelCopyWithImpl<UpdateFrequentPlaceResponseModel>(this as UpdateFrequentPlaceResponseModel, _$identity);
/// Serializes this UpdateFrequentPlaceResponseModel to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is UpdateFrequentPlaceResponseModel&&(identical(other.isUpdated, isUpdated) || other.isUpdated == isUpdated)&&(identical(other.item, item) || other.item == item));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,isUpdated,item);
@override
String toString() {
return 'UpdateFrequentPlaceResponseModel(isUpdated: $isUpdated, item: $item)';
}
}
/// @nodoc
abstract mixin class $UpdateFrequentPlaceResponseModelCopyWith<$Res> {
factory $UpdateFrequentPlaceResponseModelCopyWith(UpdateFrequentPlaceResponseModel value, $Res Function(UpdateFrequentPlaceResponseModel) _then) = _$UpdateFrequentPlaceResponseModelCopyWithImpl;
@useResult
$Res call({
bool isUpdated, FrequentPlaceItemResponseModel item
});
$FrequentPlaceItemResponseModelCopyWith<$Res> get item;
}
/// @nodoc
class _$UpdateFrequentPlaceResponseModelCopyWithImpl<$Res>
implements $UpdateFrequentPlaceResponseModelCopyWith<$Res> {
_$UpdateFrequentPlaceResponseModelCopyWithImpl(this._self, this._then);
final UpdateFrequentPlaceResponseModel _self;
final $Res Function(UpdateFrequentPlaceResponseModel) _then;
/// Create a copy of UpdateFrequentPlaceResponseModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? isUpdated = null,Object? item = null,}) {
return _then(_self.copyWith(
isUpdated: null == isUpdated ? _self.isUpdated : isUpdated // ignore: cast_nullable_to_non_nullable
as bool,item: null == item ? _self.item : item // ignore: cast_nullable_to_non_nullable
as FrequentPlaceItemResponseModel,
));
}
/// Create a copy of UpdateFrequentPlaceResponseModel
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$FrequentPlaceItemResponseModelCopyWith<$Res> get item {
return $FrequentPlaceItemResponseModelCopyWith<$Res>(_self.item, (value) {
return _then(_self.copyWith(item: value));
});
}
}
/// Adds pattern-matching-related methods to [UpdateFrequentPlaceResponseModel].
extension UpdateFrequentPlaceResponseModelPatterns on UpdateFrequentPlaceResponseModel {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _UpdateFrequentPlaceResponseModel value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _UpdateFrequentPlaceResponseModel() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _UpdateFrequentPlaceResponseModel value) $default,){
final _that = this;
switch (_that) {
case _UpdateFrequentPlaceResponseModel():
return $default(_that);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _UpdateFrequentPlaceResponseModel value)? $default,){
final _that = this;
switch (_that) {
case _UpdateFrequentPlaceResponseModel() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( bool isUpdated, FrequentPlaceItemResponseModel item)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _UpdateFrequentPlaceResponseModel() when $default != null:
return $default(_that.isUpdated,_that.item);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( bool isUpdated, FrequentPlaceItemResponseModel item) $default,) {final _that = this;
switch (_that) {
case _UpdateFrequentPlaceResponseModel():
return $default(_that.isUpdated,_that.item);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( bool isUpdated, FrequentPlaceItemResponseModel item)? $default,) {final _that = this;
switch (_that) {
case _UpdateFrequentPlaceResponseModel() when $default != null:
return $default(_that.isUpdated,_that.item);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _UpdateFrequentPlaceResponseModel implements UpdateFrequentPlaceResponseModel {
const _UpdateFrequentPlaceResponseModel({required this.isUpdated, required this.item});
factory _UpdateFrequentPlaceResponseModel.fromJson(Map<String, dynamic> json) => _$UpdateFrequentPlaceResponseModelFromJson(json);
@override final bool isUpdated;
@override final FrequentPlaceItemResponseModel item;
/// Create a copy of UpdateFrequentPlaceResponseModel
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$UpdateFrequentPlaceResponseModelCopyWith<_UpdateFrequentPlaceResponseModel> get copyWith => __$UpdateFrequentPlaceResponseModelCopyWithImpl<_UpdateFrequentPlaceResponseModel>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$UpdateFrequentPlaceResponseModelToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _UpdateFrequentPlaceResponseModel&&(identical(other.isUpdated, isUpdated) || other.isUpdated == isUpdated)&&(identical(other.item, item) || other.item == item));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,isUpdated,item);
@override
String toString() {
return 'UpdateFrequentPlaceResponseModel(isUpdated: $isUpdated, item: $item)';
}
}
/// @nodoc
abstract mixin class _$UpdateFrequentPlaceResponseModelCopyWith<$Res> implements $UpdateFrequentPlaceResponseModelCopyWith<$Res> {
factory _$UpdateFrequentPlaceResponseModelCopyWith(_UpdateFrequentPlaceResponseModel value, $Res Function(_UpdateFrequentPlaceResponseModel) _then) = __$UpdateFrequentPlaceResponseModelCopyWithImpl;
@override @useResult
$Res call({
bool isUpdated, FrequentPlaceItemResponseModel item
});
@override $FrequentPlaceItemResponseModelCopyWith<$Res> get item;
}
/// @nodoc
class __$UpdateFrequentPlaceResponseModelCopyWithImpl<$Res>
implements _$UpdateFrequentPlaceResponseModelCopyWith<$Res> {
__$UpdateFrequentPlaceResponseModelCopyWithImpl(this._self, this._then);
final _UpdateFrequentPlaceResponseModel _self;
final $Res Function(_UpdateFrequentPlaceResponseModel) _then;
/// Create a copy of UpdateFrequentPlaceResponseModel
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? isUpdated = null,Object? item = null,}) {
return _then(_UpdateFrequentPlaceResponseModel(
isUpdated: null == isUpdated ? _self.isUpdated : isUpdated // ignore: cast_nullable_to_non_nullable
as bool,item: null == item ? _self.item : item // ignore: cast_nullable_to_non_nullable
as FrequentPlaceItemResponseModel,
));
}
/// Create a copy of UpdateFrequentPlaceResponseModel
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$FrequentPlaceItemResponseModelCopyWith<$Res> get item {
return $FrequentPlaceItemResponseModelCopyWith<$Res>(_self.item, (value) {
return _then(_self.copyWith(item: value));
});
}
}
// dart format on

View File

@@ -0,0 +1,20 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'update_frequent_place_response_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_UpdateFrequentPlaceResponseModel _$UpdateFrequentPlaceResponseModelFromJson(
Map<String, dynamic> json,
) => _UpdateFrequentPlaceResponseModel(
isUpdated: json['isUpdated'] as bool,
item: FrequentPlaceItemResponseModel.fromJson(
json['item'] as Map<String, dynamic>,
),
);
Map<String, dynamic> _$UpdateFrequentPlaceResponseModelToJson(
_UpdateFrequentPlaceResponseModel instance,
) => <String, dynamic>{'isUpdated': instance.isUpdated, 'item': instance.item};

View File

@@ -0,0 +1,19 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'update_geofence_request_model.freezed.dart';
part 'update_geofence_request_model.g.dart';
@freezed
abstract class UpdateGeofenceRequestModel with _$UpdateGeofenceRequestModel {
const factory UpdateGeofenceRequestModel({
required String id,
required String name,
String? description,
required double latitude,
required double longitude,
required double radius,
}) = _UpdateGeofenceRequestModel;
factory UpdateGeofenceRequestModel.fromJson(Map<String, dynamic> json) =>
_$UpdateGeofenceRequestModelFromJson(json);
}

View File

@@ -0,0 +1,292 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// coverage:ignore-file
// 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 'update_geofence_request_model.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$UpdateGeofenceRequestModel {
String get id; String get name; String? get description; double get latitude; double get longitude; double get radius;
/// Create a copy of UpdateGeofenceRequestModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$UpdateGeofenceRequestModelCopyWith<UpdateGeofenceRequestModel> get copyWith => _$UpdateGeofenceRequestModelCopyWithImpl<UpdateGeofenceRequestModel>(this as UpdateGeofenceRequestModel, _$identity);
/// Serializes this UpdateGeofenceRequestModel to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is UpdateGeofenceRequestModel&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&(identical(other.latitude, latitude) || other.latitude == latitude)&&(identical(other.longitude, longitude) || other.longitude == longitude)&&(identical(other.radius, radius) || other.radius == radius));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,name,description,latitude,longitude,radius);
@override
String toString() {
return 'UpdateGeofenceRequestModel(id: $id, name: $name, description: $description, latitude: $latitude, longitude: $longitude, radius: $radius)';
}
}
/// @nodoc
abstract mixin class $UpdateGeofenceRequestModelCopyWith<$Res> {
factory $UpdateGeofenceRequestModelCopyWith(UpdateGeofenceRequestModel value, $Res Function(UpdateGeofenceRequestModel) _then) = _$UpdateGeofenceRequestModelCopyWithImpl;
@useResult
$Res call({
String id, String name, String? description, double latitude, double longitude, double radius
});
}
/// @nodoc
class _$UpdateGeofenceRequestModelCopyWithImpl<$Res>
implements $UpdateGeofenceRequestModelCopyWith<$Res> {
_$UpdateGeofenceRequestModelCopyWithImpl(this._self, this._then);
final UpdateGeofenceRequestModel _self;
final $Res Function(UpdateGeofenceRequestModel) _then;
/// Create a copy of UpdateGeofenceRequestModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = null,Object? description = freezed,Object? latitude = null,Object? longitude = null,Object? radius = null,}) {
return _then(_self.copyWith(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
as String?,latitude: null == latitude ? _self.latitude : latitude // ignore: cast_nullable_to_non_nullable
as double,longitude: null == longitude ? _self.longitude : longitude // ignore: cast_nullable_to_non_nullable
as double,radius: null == radius ? _self.radius : radius // ignore: cast_nullable_to_non_nullable
as double,
));
}
}
/// Adds pattern-matching-related methods to [UpdateGeofenceRequestModel].
extension UpdateGeofenceRequestModelPatterns on UpdateGeofenceRequestModel {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _UpdateGeofenceRequestModel value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _UpdateGeofenceRequestModel() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _UpdateGeofenceRequestModel value) $default,){
final _that = this;
switch (_that) {
case _UpdateGeofenceRequestModel():
return $default(_that);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _UpdateGeofenceRequestModel value)? $default,){
final _that = this;
switch (_that) {
case _UpdateGeofenceRequestModel() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String name, String? description, double latitude, double longitude, double radius)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _UpdateGeofenceRequestModel() when $default != null:
return $default(_that.id,_that.name,_that.description,_that.latitude,_that.longitude,_that.radius);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String name, String? description, double latitude, double longitude, double radius) $default,) {final _that = this;
switch (_that) {
case _UpdateGeofenceRequestModel():
return $default(_that.id,_that.name,_that.description,_that.latitude,_that.longitude,_that.radius);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String name, String? description, double latitude, double longitude, double radius)? $default,) {final _that = this;
switch (_that) {
case _UpdateGeofenceRequestModel() when $default != null:
return $default(_that.id,_that.name,_that.description,_that.latitude,_that.longitude,_that.radius);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _UpdateGeofenceRequestModel implements UpdateGeofenceRequestModel {
const _UpdateGeofenceRequestModel({required this.id, required this.name, this.description, required this.latitude, required this.longitude, required this.radius});
factory _UpdateGeofenceRequestModel.fromJson(Map<String, dynamic> json) => _$UpdateGeofenceRequestModelFromJson(json);
@override final String id;
@override final String name;
@override final String? description;
@override final double latitude;
@override final double longitude;
@override final double radius;
/// Create a copy of UpdateGeofenceRequestModel
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$UpdateGeofenceRequestModelCopyWith<_UpdateGeofenceRequestModel> get copyWith => __$UpdateGeofenceRequestModelCopyWithImpl<_UpdateGeofenceRequestModel>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$UpdateGeofenceRequestModelToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _UpdateGeofenceRequestModel&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&(identical(other.latitude, latitude) || other.latitude == latitude)&&(identical(other.longitude, longitude) || other.longitude == longitude)&&(identical(other.radius, radius) || other.radius == radius));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,name,description,latitude,longitude,radius);
@override
String toString() {
return 'UpdateGeofenceRequestModel(id: $id, name: $name, description: $description, latitude: $latitude, longitude: $longitude, radius: $radius)';
}
}
/// @nodoc
abstract mixin class _$UpdateGeofenceRequestModelCopyWith<$Res> implements $UpdateGeofenceRequestModelCopyWith<$Res> {
factory _$UpdateGeofenceRequestModelCopyWith(_UpdateGeofenceRequestModel value, $Res Function(_UpdateGeofenceRequestModel) _then) = __$UpdateGeofenceRequestModelCopyWithImpl;
@override @useResult
$Res call({
String id, String name, String? description, double latitude, double longitude, double radius
});
}
/// @nodoc
class __$UpdateGeofenceRequestModelCopyWithImpl<$Res>
implements _$UpdateGeofenceRequestModelCopyWith<$Res> {
__$UpdateGeofenceRequestModelCopyWithImpl(this._self, this._then);
final _UpdateGeofenceRequestModel _self;
final $Res Function(_UpdateGeofenceRequestModel) _then;
/// Create a copy of UpdateGeofenceRequestModel
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = null,Object? description = freezed,Object? latitude = null,Object? longitude = null,Object? radius = null,}) {
return _then(_UpdateGeofenceRequestModel(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
as String?,latitude: null == latitude ? _self.latitude : latitude // ignore: cast_nullable_to_non_nullable
as double,longitude: null == longitude ? _self.longitude : longitude // ignore: cast_nullable_to_non_nullable
as double,radius: null == radius ? _self.radius : radius // ignore: cast_nullable_to_non_nullable
as double,
));
}
}
// dart format on

View File

@@ -0,0 +1,29 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'update_geofence_request_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_UpdateGeofenceRequestModel _$UpdateGeofenceRequestModelFromJson(
Map<String, dynamic> json,
) => _UpdateGeofenceRequestModel(
id: json['id'] as String,
name: json['name'] as String,
description: json['description'] as String?,
latitude: (json['latitude'] as num).toDouble(),
longitude: (json['longitude'] as num).toDouble(),
radius: (json['radius'] as num).toDouble(),
);
Map<String, dynamic> _$UpdateGeofenceRequestModelToJson(
_UpdateGeofenceRequestModel instance,
) => <String, dynamic>{
'id': instance.id,
'name': instance.name,
'description': instance.description,
'latitude': instance.latitude,
'longitude': instance.longitude,
'radius': instance.radius,
};

View File

@@ -0,0 +1,34 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:location/src/core/data/models/geofences_response_model.dart';
import 'package:location/src/core/domain/entities/geofence_entity.dart';
part 'update_geofence_response_model.freezed.dart';
part 'update_geofence_response_model.g.dart';
@freezed
abstract class UpdateGeofenceResponseModel with _$UpdateGeofenceResponseModel {
const factory UpdateGeofenceResponseModel({
required bool isUpdated,
required GeofenceItemResponseModel item,
}) = _UpdateGeofenceResponseModel;
factory UpdateGeofenceResponseModel.fromJson(Map<String, dynamic> json) =>
_$UpdateGeofenceResponseModelFromJson(json);
}
extension UpdateGeofenceResponseModelMapper on UpdateGeofenceResponseModel {
GeofenceEntity toEntity() {
return GeofenceEntity(
id: item.id,
name: item.name,
description: item.description,
latitude: item.latitude,
longitude: item.longitude,
radius: item.radius,
isActive: item.isActive,
deviceId: item.deviceId,
createdAt: item.createdAt,
updatedAt: item.updatedAt,
);
}
}

View File

@@ -0,0 +1,298 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// coverage:ignore-file
// 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 'update_geofence_response_model.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$UpdateGeofenceResponseModel {
bool get isUpdated; GeofenceItemResponseModel get item;
/// Create a copy of UpdateGeofenceResponseModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$UpdateGeofenceResponseModelCopyWith<UpdateGeofenceResponseModel> get copyWith => _$UpdateGeofenceResponseModelCopyWithImpl<UpdateGeofenceResponseModel>(this as UpdateGeofenceResponseModel, _$identity);
/// Serializes this UpdateGeofenceResponseModel to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is UpdateGeofenceResponseModel&&(identical(other.isUpdated, isUpdated) || other.isUpdated == isUpdated)&&(identical(other.item, item) || other.item == item));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,isUpdated,item);
@override
String toString() {
return 'UpdateGeofenceResponseModel(isUpdated: $isUpdated, item: $item)';
}
}
/// @nodoc
abstract mixin class $UpdateGeofenceResponseModelCopyWith<$Res> {
factory $UpdateGeofenceResponseModelCopyWith(UpdateGeofenceResponseModel value, $Res Function(UpdateGeofenceResponseModel) _then) = _$UpdateGeofenceResponseModelCopyWithImpl;
@useResult
$Res call({
bool isUpdated, GeofenceItemResponseModel item
});
$GeofenceItemResponseModelCopyWith<$Res> get item;
}
/// @nodoc
class _$UpdateGeofenceResponseModelCopyWithImpl<$Res>
implements $UpdateGeofenceResponseModelCopyWith<$Res> {
_$UpdateGeofenceResponseModelCopyWithImpl(this._self, this._then);
final UpdateGeofenceResponseModel _self;
final $Res Function(UpdateGeofenceResponseModel) _then;
/// Create a copy of UpdateGeofenceResponseModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? isUpdated = null,Object? item = null,}) {
return _then(_self.copyWith(
isUpdated: null == isUpdated ? _self.isUpdated : isUpdated // ignore: cast_nullable_to_non_nullable
as bool,item: null == item ? _self.item : item // ignore: cast_nullable_to_non_nullable
as GeofenceItemResponseModel,
));
}
/// Create a copy of UpdateGeofenceResponseModel
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$GeofenceItemResponseModelCopyWith<$Res> get item {
return $GeofenceItemResponseModelCopyWith<$Res>(_self.item, (value) {
return _then(_self.copyWith(item: value));
});
}
}
/// Adds pattern-matching-related methods to [UpdateGeofenceResponseModel].
extension UpdateGeofenceResponseModelPatterns on UpdateGeofenceResponseModel {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _UpdateGeofenceResponseModel value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _UpdateGeofenceResponseModel() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _UpdateGeofenceResponseModel value) $default,){
final _that = this;
switch (_that) {
case _UpdateGeofenceResponseModel():
return $default(_that);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _UpdateGeofenceResponseModel value)? $default,){
final _that = this;
switch (_that) {
case _UpdateGeofenceResponseModel() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( bool isUpdated, GeofenceItemResponseModel item)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _UpdateGeofenceResponseModel() when $default != null:
return $default(_that.isUpdated,_that.item);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( bool isUpdated, GeofenceItemResponseModel item) $default,) {final _that = this;
switch (_that) {
case _UpdateGeofenceResponseModel():
return $default(_that.isUpdated,_that.item);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( bool isUpdated, GeofenceItemResponseModel item)? $default,) {final _that = this;
switch (_that) {
case _UpdateGeofenceResponseModel() when $default != null:
return $default(_that.isUpdated,_that.item);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _UpdateGeofenceResponseModel implements UpdateGeofenceResponseModel {
const _UpdateGeofenceResponseModel({required this.isUpdated, required this.item});
factory _UpdateGeofenceResponseModel.fromJson(Map<String, dynamic> json) => _$UpdateGeofenceResponseModelFromJson(json);
@override final bool isUpdated;
@override final GeofenceItemResponseModel item;
/// Create a copy of UpdateGeofenceResponseModel
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$UpdateGeofenceResponseModelCopyWith<_UpdateGeofenceResponseModel> get copyWith => __$UpdateGeofenceResponseModelCopyWithImpl<_UpdateGeofenceResponseModel>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$UpdateGeofenceResponseModelToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _UpdateGeofenceResponseModel&&(identical(other.isUpdated, isUpdated) || other.isUpdated == isUpdated)&&(identical(other.item, item) || other.item == item));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,isUpdated,item);
@override
String toString() {
return 'UpdateGeofenceResponseModel(isUpdated: $isUpdated, item: $item)';
}
}
/// @nodoc
abstract mixin class _$UpdateGeofenceResponseModelCopyWith<$Res> implements $UpdateGeofenceResponseModelCopyWith<$Res> {
factory _$UpdateGeofenceResponseModelCopyWith(_UpdateGeofenceResponseModel value, $Res Function(_UpdateGeofenceResponseModel) _then) = __$UpdateGeofenceResponseModelCopyWithImpl;
@override @useResult
$Res call({
bool isUpdated, GeofenceItemResponseModel item
});
@override $GeofenceItemResponseModelCopyWith<$Res> get item;
}
/// @nodoc
class __$UpdateGeofenceResponseModelCopyWithImpl<$Res>
implements _$UpdateGeofenceResponseModelCopyWith<$Res> {
__$UpdateGeofenceResponseModelCopyWithImpl(this._self, this._then);
final _UpdateGeofenceResponseModel _self;
final $Res Function(_UpdateGeofenceResponseModel) _then;
/// Create a copy of UpdateGeofenceResponseModel
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? isUpdated = null,Object? item = null,}) {
return _then(_UpdateGeofenceResponseModel(
isUpdated: null == isUpdated ? _self.isUpdated : isUpdated // ignore: cast_nullable_to_non_nullable
as bool,item: null == item ? _self.item : item // ignore: cast_nullable_to_non_nullable
as GeofenceItemResponseModel,
));
}
/// Create a copy of UpdateGeofenceResponseModel
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$GeofenceItemResponseModelCopyWith<$Res> get item {
return $GeofenceItemResponseModelCopyWith<$Res>(_self.item, (value) {
return _then(_self.copyWith(item: value));
});
}
}
// dart format on

View File

@@ -0,0 +1,20 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'update_geofence_response_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_UpdateGeofenceResponseModel _$UpdateGeofenceResponseModelFromJson(
Map<String, dynamic> json,
) => _UpdateGeofenceResponseModel(
isUpdated: json['isUpdated'] as bool,
item: GeofenceItemResponseModel.fromJson(
json['item'] as Map<String, dynamic>,
),
);
Map<String, dynamic> _$UpdateGeofenceResponseModelToJson(
_UpdateGeofenceResponseModel instance,
) => <String, dynamic>{'isUpdated': instance.isUpdated, 'item': instance.item};

View File

@@ -0,0 +1,64 @@
import 'package:control_panel/control_panel.dart';
import 'package:location/src/core/data/datasource/location_remote_datasource.dart';
import 'package:location/src/core/data/models/create_frequent_place_request_model.dart';
import 'package:location/src/core/data/models/create_geofence_request_model.dart';
import 'package:location/src/core/data/models/update_frequent_place_request_model.dart';
import 'package:location/src/core/data/models/update_geofence_request_model.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';
class LocationRepositoryImpl implements LocationRepository {
const LocationRepositoryImpl(this._remote);
final LocationRemoteDatasource _remote;
@override
Future<List<GeofenceEntity>> getGeofences({required String deviceId}) async =>
_remote.getGeofences(deviceId: deviceId);
@override
Future<GeofenceEntity> createGeofence(
{required CreateGeofenceRequestModel request}) async =>
_remote.createGeofence(request: request);
@override
Future<GeofenceEntity> updateGeofence(
{required UpdateGeofenceRequestModel request}) async =>
_remote.updateGeofence(request: request);
@override
Future<void> deleteGeofence({required String geofenceId}) async =>
_remote.deleteGeofence(geofenceId: geofenceId);
@override
Future<List<FrequentPlaceEntity>> getFrequentPlaces(
{required String deviceId}) async =>
_remote.getFrequentPlaces(deviceId: deviceId);
@override
Future<FrequentPlaceEntity> createFrequentPlace(
{required CreateFrequentPlaceRequestModel request}) async =>
_remote.createFrequentPlace(request: request);
@override
Future<FrequentPlaceEntity> updateFrequentPlace(
{required UpdateFrequentPlaceRequestModel request}) async =>
_remote.updateFrequentPlace(request: request);
@override
Future<void> deleteFrequentPlace({required String frequentPlaceId}) async =>
_remote.deleteFrequentPlace(frequentPlaceId: frequentPlaceId);
@override
Future<List<PositionEntity>> getPositionHistory({
required String deviceIdentificator,
required DateTime from,
required DateTime to,
}) async =>
_remote.getPositionHistory(
deviceIdentificator: deviceIdentificator,
from: from,
to: to,
);
}

View File

@@ -0,0 +1,26 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'frequent_place_entity.freezed.dart';
@freezed
abstract class WifiInfoEntity with _$WifiInfoEntity {
const factory WifiInfoEntity({
required String ssid,
required String bssid,
required String signal,
}) = _WifiInfoEntity;
}
@freezed
abstract class FrequentPlaceEntity with _$FrequentPlaceEntity {
const factory FrequentPlaceEntity({
required String id,
required String name,
required double lat,
required double lng,
@Default([]) List<WifiInfoEntity> wifiList,
String? deviceId,
required int createdAt,
int? updatedAt,
}) = _FrequentPlaceEntity;
}

View File

@@ -0,0 +1,561 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// coverage:ignore-file
// 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 'frequent_place_entity.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$WifiInfoEntity {
String get ssid; String get bssid; String get signal;
/// Create a copy of WifiInfoEntity
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$WifiInfoEntityCopyWith<WifiInfoEntity> get copyWith => _$WifiInfoEntityCopyWithImpl<WifiInfoEntity>(this as WifiInfoEntity, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is WifiInfoEntity&&(identical(other.ssid, ssid) || other.ssid == ssid)&&(identical(other.bssid, bssid) || other.bssid == bssid)&&(identical(other.signal, signal) || other.signal == signal));
}
@override
int get hashCode => Object.hash(runtimeType,ssid,bssid,signal);
@override
String toString() {
return 'WifiInfoEntity(ssid: $ssid, bssid: $bssid, signal: $signal)';
}
}
/// @nodoc
abstract mixin class $WifiInfoEntityCopyWith<$Res> {
factory $WifiInfoEntityCopyWith(WifiInfoEntity value, $Res Function(WifiInfoEntity) _then) = _$WifiInfoEntityCopyWithImpl;
@useResult
$Res call({
String ssid, String bssid, String signal
});
}
/// @nodoc
class _$WifiInfoEntityCopyWithImpl<$Res>
implements $WifiInfoEntityCopyWith<$Res> {
_$WifiInfoEntityCopyWithImpl(this._self, this._then);
final WifiInfoEntity _self;
final $Res Function(WifiInfoEntity) _then;
/// Create a copy of WifiInfoEntity
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? ssid = null,Object? bssid = null,Object? signal = null,}) {
return _then(_self.copyWith(
ssid: null == ssid ? _self.ssid : ssid // ignore: cast_nullable_to_non_nullable
as String,bssid: null == bssid ? _self.bssid : bssid // ignore: cast_nullable_to_non_nullable
as String,signal: null == signal ? _self.signal : signal // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
/// Adds pattern-matching-related methods to [WifiInfoEntity].
extension WifiInfoEntityPatterns on WifiInfoEntity {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _WifiInfoEntity value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _WifiInfoEntity() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _WifiInfoEntity value) $default,){
final _that = this;
switch (_that) {
case _WifiInfoEntity():
return $default(_that);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _WifiInfoEntity value)? $default,){
final _that = this;
switch (_that) {
case _WifiInfoEntity() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String ssid, String bssid, String signal)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _WifiInfoEntity() when $default != null:
return $default(_that.ssid,_that.bssid,_that.signal);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String ssid, String bssid, String signal) $default,) {final _that = this;
switch (_that) {
case _WifiInfoEntity():
return $default(_that.ssid,_that.bssid,_that.signal);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String ssid, String bssid, String signal)? $default,) {final _that = this;
switch (_that) {
case _WifiInfoEntity() when $default != null:
return $default(_that.ssid,_that.bssid,_that.signal);case _:
return null;
}
}
}
/// @nodoc
class _WifiInfoEntity implements WifiInfoEntity {
const _WifiInfoEntity({required this.ssid, required this.bssid, required this.signal});
@override final String ssid;
@override final String bssid;
@override final String signal;
/// Create a copy of WifiInfoEntity
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$WifiInfoEntityCopyWith<_WifiInfoEntity> get copyWith => __$WifiInfoEntityCopyWithImpl<_WifiInfoEntity>(this, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _WifiInfoEntity&&(identical(other.ssid, ssid) || other.ssid == ssid)&&(identical(other.bssid, bssid) || other.bssid == bssid)&&(identical(other.signal, signal) || other.signal == signal));
}
@override
int get hashCode => Object.hash(runtimeType,ssid,bssid,signal);
@override
String toString() {
return 'WifiInfoEntity(ssid: $ssid, bssid: $bssid, signal: $signal)';
}
}
/// @nodoc
abstract mixin class _$WifiInfoEntityCopyWith<$Res> implements $WifiInfoEntityCopyWith<$Res> {
factory _$WifiInfoEntityCopyWith(_WifiInfoEntity value, $Res Function(_WifiInfoEntity) _then) = __$WifiInfoEntityCopyWithImpl;
@override @useResult
$Res call({
String ssid, String bssid, String signal
});
}
/// @nodoc
class __$WifiInfoEntityCopyWithImpl<$Res>
implements _$WifiInfoEntityCopyWith<$Res> {
__$WifiInfoEntityCopyWithImpl(this._self, this._then);
final _WifiInfoEntity _self;
final $Res Function(_WifiInfoEntity) _then;
/// Create a copy of WifiInfoEntity
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? ssid = null,Object? bssid = null,Object? signal = null,}) {
return _then(_WifiInfoEntity(
ssid: null == ssid ? _self.ssid : ssid // ignore: cast_nullable_to_non_nullable
as String,bssid: null == bssid ? _self.bssid : bssid // ignore: cast_nullable_to_non_nullable
as String,signal: null == signal ? _self.signal : signal // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
/// @nodoc
mixin _$FrequentPlaceEntity {
String get id; String get name; double get lat; double get lng; List<WifiInfoEntity> get wifiList; String? get deviceId; int get createdAt; int? get updatedAt;
/// Create a copy of FrequentPlaceEntity
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$FrequentPlaceEntityCopyWith<FrequentPlaceEntity> get copyWith => _$FrequentPlaceEntityCopyWithImpl<FrequentPlaceEntity>(this as FrequentPlaceEntity, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is FrequentPlaceEntity&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.lat, lat) || other.lat == lat)&&(identical(other.lng, lng) || other.lng == lng)&&const DeepCollectionEquality().equals(other.wifiList, wifiList)&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt));
}
@override
int get hashCode => Object.hash(runtimeType,id,name,lat,lng,const DeepCollectionEquality().hash(wifiList),deviceId,createdAt,updatedAt);
@override
String toString() {
return 'FrequentPlaceEntity(id: $id, name: $name, lat: $lat, lng: $lng, wifiList: $wifiList, deviceId: $deviceId, createdAt: $createdAt, updatedAt: $updatedAt)';
}
}
/// @nodoc
abstract mixin class $FrequentPlaceEntityCopyWith<$Res> {
factory $FrequentPlaceEntityCopyWith(FrequentPlaceEntity value, $Res Function(FrequentPlaceEntity) _then) = _$FrequentPlaceEntityCopyWithImpl;
@useResult
$Res call({
String id, String name, double lat, double lng, List<WifiInfoEntity> wifiList, String? deviceId, int createdAt, int? updatedAt
});
}
/// @nodoc
class _$FrequentPlaceEntityCopyWithImpl<$Res>
implements $FrequentPlaceEntityCopyWith<$Res> {
_$FrequentPlaceEntityCopyWithImpl(this._self, this._then);
final FrequentPlaceEntity _self;
final $Res Function(FrequentPlaceEntity) _then;
/// Create a copy of FrequentPlaceEntity
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = null,Object? lat = null,Object? lng = null,Object? wifiList = null,Object? deviceId = freezed,Object? createdAt = null,Object? updatedAt = freezed,}) {
return _then(_self.copyWith(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String,lat: null == lat ? _self.lat : lat // ignore: cast_nullable_to_non_nullable
as double,lng: null == lng ? _self.lng : lng // ignore: cast_nullable_to_non_nullable
as double,wifiList: null == wifiList ? _self.wifiList : wifiList // ignore: cast_nullable_to_non_nullable
as List<WifiInfoEntity>,deviceId: freezed == deviceId ? _self.deviceId : deviceId // ignore: cast_nullable_to_non_nullable
as String?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
as int,updatedAt: freezed == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
as int?,
));
}
}
/// Adds pattern-matching-related methods to [FrequentPlaceEntity].
extension FrequentPlaceEntityPatterns on FrequentPlaceEntity {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _FrequentPlaceEntity value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _FrequentPlaceEntity() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _FrequentPlaceEntity value) $default,){
final _that = this;
switch (_that) {
case _FrequentPlaceEntity():
return $default(_that);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _FrequentPlaceEntity value)? $default,){
final _that = this;
switch (_that) {
case _FrequentPlaceEntity() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String name, double lat, double lng, List<WifiInfoEntity> wifiList, String? deviceId, int createdAt, int? updatedAt)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _FrequentPlaceEntity() when $default != null:
return $default(_that.id,_that.name,_that.lat,_that.lng,_that.wifiList,_that.deviceId,_that.createdAt,_that.updatedAt);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String name, double lat, double lng, List<WifiInfoEntity> wifiList, String? deviceId, int createdAt, int? updatedAt) $default,) {final _that = this;
switch (_that) {
case _FrequentPlaceEntity():
return $default(_that.id,_that.name,_that.lat,_that.lng,_that.wifiList,_that.deviceId,_that.createdAt,_that.updatedAt);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String name, double lat, double lng, List<WifiInfoEntity> wifiList, String? deviceId, int createdAt, int? updatedAt)? $default,) {final _that = this;
switch (_that) {
case _FrequentPlaceEntity() when $default != null:
return $default(_that.id,_that.name,_that.lat,_that.lng,_that.wifiList,_that.deviceId,_that.createdAt,_that.updatedAt);case _:
return null;
}
}
}
/// @nodoc
class _FrequentPlaceEntity implements FrequentPlaceEntity {
const _FrequentPlaceEntity({required this.id, required this.name, required this.lat, required this.lng, final List<WifiInfoEntity> wifiList = const [], this.deviceId, required this.createdAt, this.updatedAt}): _wifiList = wifiList;
@override final String id;
@override final String name;
@override final double lat;
@override final double lng;
final List<WifiInfoEntity> _wifiList;
@override@JsonKey() List<WifiInfoEntity> get wifiList {
if (_wifiList is EqualUnmodifiableListView) return _wifiList;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_wifiList);
}
@override final String? deviceId;
@override final int createdAt;
@override final int? updatedAt;
/// Create a copy of FrequentPlaceEntity
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$FrequentPlaceEntityCopyWith<_FrequentPlaceEntity> get copyWith => __$FrequentPlaceEntityCopyWithImpl<_FrequentPlaceEntity>(this, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _FrequentPlaceEntity&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.lat, lat) || other.lat == lat)&&(identical(other.lng, lng) || other.lng == lng)&&const DeepCollectionEquality().equals(other._wifiList, _wifiList)&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt));
}
@override
int get hashCode => Object.hash(runtimeType,id,name,lat,lng,const DeepCollectionEquality().hash(_wifiList),deviceId,createdAt,updatedAt);
@override
String toString() {
return 'FrequentPlaceEntity(id: $id, name: $name, lat: $lat, lng: $lng, wifiList: $wifiList, deviceId: $deviceId, createdAt: $createdAt, updatedAt: $updatedAt)';
}
}
/// @nodoc
abstract mixin class _$FrequentPlaceEntityCopyWith<$Res> implements $FrequentPlaceEntityCopyWith<$Res> {
factory _$FrequentPlaceEntityCopyWith(_FrequentPlaceEntity value, $Res Function(_FrequentPlaceEntity) _then) = __$FrequentPlaceEntityCopyWithImpl;
@override @useResult
$Res call({
String id, String name, double lat, double lng, List<WifiInfoEntity> wifiList, String? deviceId, int createdAt, int? updatedAt
});
}
/// @nodoc
class __$FrequentPlaceEntityCopyWithImpl<$Res>
implements _$FrequentPlaceEntityCopyWith<$Res> {
__$FrequentPlaceEntityCopyWithImpl(this._self, this._then);
final _FrequentPlaceEntity _self;
final $Res Function(_FrequentPlaceEntity) _then;
/// Create a copy of FrequentPlaceEntity
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = null,Object? lat = null,Object? lng = null,Object? wifiList = null,Object? deviceId = freezed,Object? createdAt = null,Object? updatedAt = freezed,}) {
return _then(_FrequentPlaceEntity(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String,lat: null == lat ? _self.lat : lat // ignore: cast_nullable_to_non_nullable
as double,lng: null == lng ? _self.lng : lng // ignore: cast_nullable_to_non_nullable
as double,wifiList: null == wifiList ? _self._wifiList : wifiList // ignore: cast_nullable_to_non_nullable
as List<WifiInfoEntity>,deviceId: freezed == deviceId ? _self.deviceId : deviceId // ignore: cast_nullable_to_non_nullable
as String?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
as int,updatedAt: freezed == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
as int?,
));
}
}
// dart format on

View File

@@ -0,0 +1,19 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'geofence_entity.freezed.dart';
@freezed
abstract class GeofenceEntity with _$GeofenceEntity {
const factory GeofenceEntity({
required String id,
required String name,
String? description,
required double latitude,
required double longitude,
required double radius,
required bool isActive,
String? deviceId,
required int createdAt,
int? updatedAt,
}) = _GeofenceEntity;
}

View File

@@ -0,0 +1,298 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// coverage:ignore-file
// 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 'geofence_entity.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$GeofenceEntity {
String get id; String get name; String? get description; double get latitude; double get longitude; double get radius; bool get isActive; String? get deviceId; int get createdAt; int? get updatedAt;
/// Create a copy of GeofenceEntity
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$GeofenceEntityCopyWith<GeofenceEntity> get copyWith => _$GeofenceEntityCopyWithImpl<GeofenceEntity>(this as GeofenceEntity, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is GeofenceEntity&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&(identical(other.latitude, latitude) || other.latitude == latitude)&&(identical(other.longitude, longitude) || other.longitude == longitude)&&(identical(other.radius, radius) || other.radius == radius)&&(identical(other.isActive, isActive) || other.isActive == isActive)&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt));
}
@override
int get hashCode => Object.hash(runtimeType,id,name,description,latitude,longitude,radius,isActive,deviceId,createdAt,updatedAt);
@override
String toString() {
return 'GeofenceEntity(id: $id, name: $name, description: $description, latitude: $latitude, longitude: $longitude, radius: $radius, isActive: $isActive, deviceId: $deviceId, createdAt: $createdAt, updatedAt: $updatedAt)';
}
}
/// @nodoc
abstract mixin class $GeofenceEntityCopyWith<$Res> {
factory $GeofenceEntityCopyWith(GeofenceEntity value, $Res Function(GeofenceEntity) _then) = _$GeofenceEntityCopyWithImpl;
@useResult
$Res call({
String id, String name, String? description, double latitude, double longitude, double radius, bool isActive, String? deviceId, int createdAt, int? updatedAt
});
}
/// @nodoc
class _$GeofenceEntityCopyWithImpl<$Res>
implements $GeofenceEntityCopyWith<$Res> {
_$GeofenceEntityCopyWithImpl(this._self, this._then);
final GeofenceEntity _self;
final $Res Function(GeofenceEntity) _then;
/// Create a copy of GeofenceEntity
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = null,Object? description = freezed,Object? latitude = null,Object? longitude = null,Object? radius = null,Object? isActive = null,Object? deviceId = freezed,Object? createdAt = null,Object? updatedAt = freezed,}) {
return _then(_self.copyWith(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
as String?,latitude: null == latitude ? _self.latitude : latitude // ignore: cast_nullable_to_non_nullable
as double,longitude: null == longitude ? _self.longitude : longitude // ignore: cast_nullable_to_non_nullable
as double,radius: null == radius ? _self.radius : radius // ignore: cast_nullable_to_non_nullable
as double,isActive: null == isActive ? _self.isActive : isActive // ignore: cast_nullable_to_non_nullable
as bool,deviceId: freezed == deviceId ? _self.deviceId : deviceId // ignore: cast_nullable_to_non_nullable
as String?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
as int,updatedAt: freezed == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
as int?,
));
}
}
/// Adds pattern-matching-related methods to [GeofenceEntity].
extension GeofenceEntityPatterns on GeofenceEntity {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _GeofenceEntity value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _GeofenceEntity() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _GeofenceEntity value) $default,){
final _that = this;
switch (_that) {
case _GeofenceEntity():
return $default(_that);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _GeofenceEntity value)? $default,){
final _that = this;
switch (_that) {
case _GeofenceEntity() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String name, String? description, double latitude, double longitude, double radius, bool isActive, String? deviceId, int createdAt, int? updatedAt)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _GeofenceEntity() when $default != null:
return $default(_that.id,_that.name,_that.description,_that.latitude,_that.longitude,_that.radius,_that.isActive,_that.deviceId,_that.createdAt,_that.updatedAt);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String name, String? description, double latitude, double longitude, double radius, bool isActive, String? deviceId, int createdAt, int? updatedAt) $default,) {final _that = this;
switch (_that) {
case _GeofenceEntity():
return $default(_that.id,_that.name,_that.description,_that.latitude,_that.longitude,_that.radius,_that.isActive,_that.deviceId,_that.createdAt,_that.updatedAt);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String name, String? description, double latitude, double longitude, double radius, bool isActive, String? deviceId, int createdAt, int? updatedAt)? $default,) {final _that = this;
switch (_that) {
case _GeofenceEntity() when $default != null:
return $default(_that.id,_that.name,_that.description,_that.latitude,_that.longitude,_that.radius,_that.isActive,_that.deviceId,_that.createdAt,_that.updatedAt);case _:
return null;
}
}
}
/// @nodoc
class _GeofenceEntity implements GeofenceEntity {
const _GeofenceEntity({required this.id, required this.name, this.description, required this.latitude, required this.longitude, required this.radius, required this.isActive, this.deviceId, required this.createdAt, this.updatedAt});
@override final String id;
@override final String name;
@override final String? description;
@override final double latitude;
@override final double longitude;
@override final double radius;
@override final bool isActive;
@override final String? deviceId;
@override final int createdAt;
@override final int? updatedAt;
/// Create a copy of GeofenceEntity
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$GeofenceEntityCopyWith<_GeofenceEntity> get copyWith => __$GeofenceEntityCopyWithImpl<_GeofenceEntity>(this, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _GeofenceEntity&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&(identical(other.latitude, latitude) || other.latitude == latitude)&&(identical(other.longitude, longitude) || other.longitude == longitude)&&(identical(other.radius, radius) || other.radius == radius)&&(identical(other.isActive, isActive) || other.isActive == isActive)&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt));
}
@override
int get hashCode => Object.hash(runtimeType,id,name,description,latitude,longitude,radius,isActive,deviceId,createdAt,updatedAt);
@override
String toString() {
return 'GeofenceEntity(id: $id, name: $name, description: $description, latitude: $latitude, longitude: $longitude, radius: $radius, isActive: $isActive, deviceId: $deviceId, createdAt: $createdAt, updatedAt: $updatedAt)';
}
}
/// @nodoc
abstract mixin class _$GeofenceEntityCopyWith<$Res> implements $GeofenceEntityCopyWith<$Res> {
factory _$GeofenceEntityCopyWith(_GeofenceEntity value, $Res Function(_GeofenceEntity) _then) = __$GeofenceEntityCopyWithImpl;
@override @useResult
$Res call({
String id, String name, String? description, double latitude, double longitude, double radius, bool isActive, String? deviceId, int createdAt, int? updatedAt
});
}
/// @nodoc
class __$GeofenceEntityCopyWithImpl<$Res>
implements _$GeofenceEntityCopyWith<$Res> {
__$GeofenceEntityCopyWithImpl(this._self, this._then);
final _GeofenceEntity _self;
final $Res Function(_GeofenceEntity) _then;
/// Create a copy of GeofenceEntity
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = null,Object? description = freezed,Object? latitude = null,Object? longitude = null,Object? radius = null,Object? isActive = null,Object? deviceId = freezed,Object? createdAt = null,Object? updatedAt = freezed,}) {
return _then(_GeofenceEntity(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
as String?,latitude: null == latitude ? _self.latitude : latitude // ignore: cast_nullable_to_non_nullable
as double,longitude: null == longitude ? _self.longitude : longitude // ignore: cast_nullable_to_non_nullable
as double,radius: null == radius ? _self.radius : radius // ignore: cast_nullable_to_non_nullable
as double,isActive: null == isActive ? _self.isActive : isActive // ignore: cast_nullable_to_non_nullable
as bool,deviceId: freezed == deviceId ? _self.deviceId : deviceId // ignore: cast_nullable_to_non_nullable
as String?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
as int,updatedAt: freezed == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
as int?,
));
}
}
// dart format on

View File

@@ -0,0 +1,25 @@
import 'package:control_panel/control_panel.dart';
import 'package:location/src/core/data/models/create_frequent_place_request_model.dart';
import 'package:location/src/core/data/models/create_geofence_request_model.dart';
import 'package:location/src/core/data/models/update_frequent_place_request_model.dart';
import 'package:location/src/core/data/models/update_geofence_request_model.dart';
import 'package:location/src/core/domain/entities/geofence_entity.dart';
import 'package:location/src/core/domain/entities/frequent_place_entity.dart';
abstract class LocationRepository {
Future<List<GeofenceEntity>> getGeofences({required String deviceId});
Future<GeofenceEntity> createGeofence({required CreateGeofenceRequestModel request});
Future<GeofenceEntity> updateGeofence({required UpdateGeofenceRequestModel request});
Future<void> deleteGeofence({required String geofenceId});
Future<List<FrequentPlaceEntity>> getFrequentPlaces({required String deviceId});
Future<FrequentPlaceEntity> createFrequentPlace({required CreateFrequentPlaceRequestModel request});
Future<FrequentPlaceEntity> updateFrequentPlace({required UpdateFrequentPlaceRequestModel request});
Future<void> deleteFrequentPlace({required String frequentPlaceId});
Future<List<PositionEntity>> getPositionHistory({
required String deviceIdentificator,
required DateTime from,
required DateTime to,
});
}

View File

@@ -0,0 +1,10 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:location/src/core/data/datasource/location_remote_datasource.dart';
import 'package:location/src/core/data/datasource/location_remote_datasource_impl.dart';
import 'package:sf_infrastructure/sf_infrastructure.dart';
final locationRemoteDatasourceProvider =
Provider<LocationRemoteDatasource>((ref) {
final questiaRepository = getIt<QuestiaRepository>();
return LocationRemoteDatasourceImpl(questiaRepository);
});

View File

@@ -0,0 +1,9 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:location/src/core/data/repositories/location_repository_impl.dart';
import 'package:location/src/core/domain/repositories/location_repository.dart';
import 'package:location/src/core/providers/location_remote_datasource_provider.dart';
final locationRepositoryProvider = Provider<LocationRepository>((ref) {
final remote = ref.read(locationRemoteDatasourceProvider);
return LocationRepositoryImpl(remote);
});

View File

@@ -2,8 +2,10 @@ import 'package:control_panel/control_panel.dart';
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:legacy_shared/legacy_shared.dart';
import 'package:location/src/features/location/presentation/state/location_view_model.dart';
import 'package:location/src/features/location/presentation/widgets/location_map.dart';
import 'package:sf_localizations/sf_localizations.dart';
import 'package:utils/utils.dart';
class LocationScreen extends ConsumerWidget {
const LocationScreen({super.key});
@@ -11,33 +13,41 @@ class LocationScreen extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final theme = ref.watch(themePortProvider);
final state = ref.watch(controlPanelViewModelProvider);
final controlPanelState = ref.watch(controlPanelViewModelProvider);
final locationState = ref.watch(locationViewModelProvider);
if (state.isLoading) {
return Scaffold(
backgroundColor: theme.getColorFor(ThemeCode.backgroundPrimary),
if (controlPanelState.isLoading) {
return LegacyPageLayout(
theme: theme,
title: context.translate(I18n.location),
showBack: false,
body: const Center(child: CircularProgressIndicator()),
);
}
return Scaffold(
backgroundColor: theme.getColorFor(ThemeCode.backgroundPrimary),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.symmetric(
horizontal: 14,
vertical: SizeUtils.getByScreen(small: 12, big: 14),
),
),
Expanded(
child: DeviceMap(
selectedPosition: state.selectedPosition,
selectedDevice: state.selectedDevice,
),
),
],
return LegacyPageLayout(
theme: theme,
title: context.translate(I18n.location),
showBack: false,
body: LocationMap(
selectedPosition: controlPanelState.selectedPosition,
selectedDevice: controlPanelState.selectedDevice,
devices: controlPanelState.devices,
geofences: locationState.geofences,
frequentPlaces: locationState.frequentPlaces,
positionHistory: locationState.positionHistory,
showRouteTrail: locationState.showRouteTrail,
isLoadingHistory: locationState.isLoadingHistory,
onDeviceChanged: (device) {
ref
.read(controlPanelViewModelProvider.notifier)
.setSelectedDevice(device);
},
onRefreshPosition: () {
ref
.read(controlPanelViewModelProvider.notifier)
.refreshPositions();
},
),
);
}

View File

@@ -0,0 +1,109 @@
import 'package:control_panel/control_panel.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:location/src/core/domain/entities/frequent_place_entity.dart';
import 'package:location/src/features/location/presentation/state/location_map_view_state.dart';
final locationMapViewModelProvider =
NotifierProvider.autoDispose<LocationMapViewModel, LocationMapViewState>(
LocationMapViewModel.new,
);
class LocationMapViewModel extends Notifier<LocationMapViewState> {
@override
LocationMapViewState build() {
return const LocationMapViewState();
}
void toggleGeofences() {
state = state.copyWith(showGeofences: !state.showGeofences);
}
void toggleFrequentPlaces() {
state = state.copyWith(showFrequentPlaces: !state.showFrequentPlaces);
}
void startPlacing(PlacingMode mode) {
state = state.copyWith(placingMode: mode);
}
void cancelPlacing() {
state = state.copyWith(
placingMode: PlacingMode.none,
adjustingRadius: false,
previewPoint: null,
);
}
void confirmGeofencePlacement(LatLng center) {
state = state.copyWith(
placingMode: PlacingMode.none,
adjustingRadius: true,
previewPoint: center,
previewRadius: 200,
);
}
void confirmFrequentPlacePlacement() {
state = state.copyWith(
placingMode: PlacingMode.none,
previewPoint: null,
);
}
void updatePreviewRadius(double radius) {
state = state.copyWith(previewRadius: radius);
}
void confirmRadius() {
state = state.copyWith(
adjustingRadius: false,
editingGeofence: null,
);
}
void clearPreviewPoint() {
state = state.copyWith(previewPoint: null);
}
void selectGeofence(GeofenceEntity geofence) {
state = state.copyWith(
selectedGeofence: geofence,
selectedFrequentPlace: null,
);
}
void clearSelectedGeofence() {
state = state.copyWith(selectedGeofence: null);
}
void startEditingGeofence(GeofenceEntity geofence) {
state = state.copyWith(
selectedGeofence: null,
editingGeofence: geofence,
previewPoint: LatLng(geofence.latitude, geofence.longitude),
previewRadius: geofence.radius,
adjustingRadius: true,
);
}
void selectFrequentPlace(FrequentPlaceEntity place) {
state = state.copyWith(
selectedFrequentPlace: place,
selectedGeofence: null,
);
}
void clearSelectedFrequentPlace() {
state = state.copyWith(selectedFrequentPlace: null);
}
void selectHistoryPosition(PositionEntity position) {
state = state.copyWith(selectedHistoryPosition: position);
}
void clearSelectedHistoryPosition() {
state = state.copyWith(selectedHistoryPosition: null);
}
}

View File

@@ -0,0 +1,25 @@
import 'package:control_panel/control_panel.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:location/src/core/domain/entities/frequent_place_entity.dart';
part 'location_map_view_state.freezed.dart';
enum PlacingMode { none, geofence, frequentPlace }
@freezed
abstract class LocationMapViewState with _$LocationMapViewState {
const factory LocationMapViewState({
@Default(true) bool showGeofences,
@Default(true) bool showFrequentPlaces,
@Default(PlacingMode.none) PlacingMode placingMode,
@Default(false) bool adjustingRadius,
@Default(200.0) double previewRadius,
LatLng? previewPoint,
GeofenceEntity? selectedGeofence,
GeofenceEntity? editingGeofence,
FrequentPlaceEntity? selectedFrequentPlace,
PositionEntity? selectedHistoryPosition,
}) = _LocationMapViewState;
}

View File

@@ -0,0 +1,394 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// coverage:ignore-file
// 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';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$LocationMapViewState {
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;
/// Create a copy of LocationMapViewState
/// 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);
@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));
}
@override
int get hashCode => Object.hash(runtimeType,showGeofences,showFrequentPlaces,placingMode,adjustingRadius,previewRadius,previewPoint,selectedGeofence,editingGeofence,selectedFrequentPlace,selectedHistoryPosition);
@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)';
}
}
/// @nodoc
abstract mixin class $LocationMapViewStateCopyWith<$Res> {
factory $LocationMapViewStateCopyWith(LocationMapViewState value, $Res Function(LocationMapViewState) _then) = _$LocationMapViewStateCopyWithImpl;
@useResult
$Res call({
bool showGeofences, bool showFrequentPlaces, PlacingMode placingMode, bool adjustingRadius, double previewRadius, LatLng? previewPoint, GeofenceEntity? selectedGeofence, GeofenceEntity? editingGeofence, FrequentPlaceEntity? selectedFrequentPlace, PositionEntity? selectedHistoryPosition
});
$GeofenceEntityCopyWith<$Res>? get selectedGeofence;$GeofenceEntityCopyWith<$Res>? get editingGeofence;$FrequentPlaceEntityCopyWith<$Res>? get selectedFrequentPlace;$PositionEntityCopyWith<$Res>? get selectedHistoryPosition;
}
/// @nodoc
class _$LocationMapViewStateCopyWithImpl<$Res>
implements $LocationMapViewStateCopyWith<$Res> {
_$LocationMapViewStateCopyWithImpl(this._self, this._then);
final LocationMapViewState _self;
final $Res Function(LocationMapViewState) _then;
/// Create a copy of LocationMapViewState
/// 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,}) {
return _then(_self.copyWith(
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
as PlacingMode,adjustingRadius: null == adjustingRadius ? _self.adjustingRadius : adjustingRadius // ignore: cast_nullable_to_non_nullable
as bool,previewRadius: null == previewRadius ? _self.previewRadius : previewRadius // ignore: cast_nullable_to_non_nullable
as double,previewPoint: freezed == previewPoint ? _self.previewPoint : previewPoint // ignore: cast_nullable_to_non_nullable
as LatLng?,selectedGeofence: freezed == selectedGeofence ? _self.selectedGeofence : selectedGeofence // ignore: cast_nullable_to_non_nullable
as GeofenceEntity?,editingGeofence: freezed == editingGeofence ? _self.editingGeofence : editingGeofence // ignore: cast_nullable_to_non_nullable
as GeofenceEntity?,selectedFrequentPlace: freezed == selectedFrequentPlace ? _self.selectedFrequentPlace : selectedFrequentPlace // ignore: cast_nullable_to_non_nullable
as FrequentPlaceEntity?,selectedHistoryPosition: freezed == selectedHistoryPosition ? _self.selectedHistoryPosition : selectedHistoryPosition // ignore: cast_nullable_to_non_nullable
as PositionEntity?,
));
}
/// Create a copy of LocationMapViewState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$GeofenceEntityCopyWith<$Res>? get selectedGeofence {
if (_self.selectedGeofence == null) {
return null;
}
return $GeofenceEntityCopyWith<$Res>(_self.selectedGeofence!, (value) {
return _then(_self.copyWith(selectedGeofence: value));
});
}/// Create a copy of LocationMapViewState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$GeofenceEntityCopyWith<$Res>? get editingGeofence {
if (_self.editingGeofence == null) {
return null;
}
return $GeofenceEntityCopyWith<$Res>(_self.editingGeofence!, (value) {
return _then(_self.copyWith(editingGeofence: value));
});
}/// Create a copy of LocationMapViewState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$FrequentPlaceEntityCopyWith<$Res>? get selectedFrequentPlace {
if (_self.selectedFrequentPlace == null) {
return null;
}
return $FrequentPlaceEntityCopyWith<$Res>(_self.selectedFrequentPlace!, (value) {
return _then(_self.copyWith(selectedFrequentPlace: value));
});
}/// Create a copy of LocationMapViewState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$PositionEntityCopyWith<$Res>? get selectedHistoryPosition {
if (_self.selectedHistoryPosition == null) {
return null;
}
return $PositionEntityCopyWith<$Res>(_self.selectedHistoryPosition!, (value) {
return _then(_self.copyWith(selectedHistoryPosition: value));
});
}
}
/// Adds pattern-matching-related methods to [LocationMapViewState].
extension LocationMapViewStatePatterns on LocationMapViewState {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _LocationMapViewState value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _LocationMapViewState() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _LocationMapViewState value) $default,){
final _that = this;
switch (_that) {
case _LocationMapViewState():
return $default(_that);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _LocationMapViewState value)? $default,){
final _that = this;
switch (_that) {
case _LocationMapViewState() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@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)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _LocationMapViewState() 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);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@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) $default,) {final _that = this;
switch (_that) {
case _LocationMapViewState():
return $default(_that.showGeofences,_that.showFrequentPlaces,_that.placingMode,_that.adjustingRadius,_that.previewRadius,_that.previewPoint,_that.selectedGeofence,_that.editingGeofence,_that.selectedFrequentPlace,_that.selectedHistoryPosition);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@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)? $default,) {final _that = this;
switch (_that) {
case _LocationMapViewState() 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);case _:
return null;
}
}
}
/// @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});
@override@JsonKey() final bool showGeofences;
@override@JsonKey() final bool showFrequentPlaces;
@override@JsonKey() final PlacingMode placingMode;
@override@JsonKey() final bool adjustingRadius;
@override@JsonKey() final double previewRadius;
@override final LatLng? previewPoint;
@override final GeofenceEntity? selectedGeofence;
@override final GeofenceEntity? editingGeofence;
@override final FrequentPlaceEntity? selectedFrequentPlace;
@override final PositionEntity? selectedHistoryPosition;
/// Create a copy of LocationMapViewState
/// 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);
@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));
}
@override
int get hashCode => Object.hash(runtimeType,showGeofences,showFrequentPlaces,placingMode,adjustingRadius,previewRadius,previewPoint,selectedGeofence,editingGeofence,selectedFrequentPlace,selectedHistoryPosition);
@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)';
}
}
/// @nodoc
abstract mixin class _$LocationMapViewStateCopyWith<$Res> implements $LocationMapViewStateCopyWith<$Res> {
factory _$LocationMapViewStateCopyWith(_LocationMapViewState value, $Res Function(_LocationMapViewState) _then) = __$LocationMapViewStateCopyWithImpl;
@override @useResult
$Res call({
bool showGeofences, bool showFrequentPlaces, PlacingMode placingMode, bool adjustingRadius, double previewRadius, LatLng? previewPoint, GeofenceEntity? selectedGeofence, GeofenceEntity? editingGeofence, FrequentPlaceEntity? selectedFrequentPlace, PositionEntity? selectedHistoryPosition
});
@override $GeofenceEntityCopyWith<$Res>? get selectedGeofence;@override $GeofenceEntityCopyWith<$Res>? get editingGeofence;@override $FrequentPlaceEntityCopyWith<$Res>? get selectedFrequentPlace;@override $PositionEntityCopyWith<$Res>? get selectedHistoryPosition;
}
/// @nodoc
class __$LocationMapViewStateCopyWithImpl<$Res>
implements _$LocationMapViewStateCopyWith<$Res> {
__$LocationMapViewStateCopyWithImpl(this._self, this._then);
final _LocationMapViewState _self;
final $Res Function(_LocationMapViewState) _then;
/// Create a copy of LocationMapViewState
/// 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,}) {
return _then(_LocationMapViewState(
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
as PlacingMode,adjustingRadius: null == adjustingRadius ? _self.adjustingRadius : adjustingRadius // ignore: cast_nullable_to_non_nullable
as bool,previewRadius: null == previewRadius ? _self.previewRadius : previewRadius // ignore: cast_nullable_to_non_nullable
as double,previewPoint: freezed == previewPoint ? _self.previewPoint : previewPoint // ignore: cast_nullable_to_non_nullable
as LatLng?,selectedGeofence: freezed == selectedGeofence ? _self.selectedGeofence : selectedGeofence // ignore: cast_nullable_to_non_nullable
as GeofenceEntity?,editingGeofence: freezed == editingGeofence ? _self.editingGeofence : editingGeofence // ignore: cast_nullable_to_non_nullable
as GeofenceEntity?,selectedFrequentPlace: freezed == selectedFrequentPlace ? _self.selectedFrequentPlace : selectedFrequentPlace // ignore: cast_nullable_to_non_nullable
as FrequentPlaceEntity?,selectedHistoryPosition: freezed == selectedHistoryPosition ? _self.selectedHistoryPosition : selectedHistoryPosition // ignore: cast_nullable_to_non_nullable
as PositionEntity?,
));
}
/// Create a copy of LocationMapViewState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$GeofenceEntityCopyWith<$Res>? get selectedGeofence {
if (_self.selectedGeofence == null) {
return null;
}
return $GeofenceEntityCopyWith<$Res>(_self.selectedGeofence!, (value) {
return _then(_self.copyWith(selectedGeofence: value));
});
}/// Create a copy of LocationMapViewState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$GeofenceEntityCopyWith<$Res>? get editingGeofence {
if (_self.editingGeofence == null) {
return null;
}
return $GeofenceEntityCopyWith<$Res>(_self.editingGeofence!, (value) {
return _then(_self.copyWith(editingGeofence: value));
});
}/// Create a copy of LocationMapViewState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$FrequentPlaceEntityCopyWith<$Res>? get selectedFrequentPlace {
if (_self.selectedFrequentPlace == null) {
return null;
}
return $FrequentPlaceEntityCopyWith<$Res>(_self.selectedFrequentPlace!, (value) {
return _then(_self.copyWith(selectedFrequentPlace: value));
});
}/// Create a copy of LocationMapViewState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$PositionEntityCopyWith<$Res>? get selectedHistoryPosition {
if (_self.selectedHistoryPosition == null) {
return null;
}
return $PositionEntityCopyWith<$Res>(_self.selectedHistoryPosition!, (value) {
return _then(_self.copyWith(selectedHistoryPosition: value));
});
}
}
// dart format on

View File

@@ -0,0 +1,278 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:legacy_shared/legacy_shared.dart';
import 'package:location/src/core/data/models/create_frequent_place_request_model.dart';
import 'package:location/src/core/data/models/create_geofence_request_model.dart';
import 'package:location/src/core/data/models/frequent_places_response_model.dart';
import 'package:location/src/core/data/models/update_frequent_place_request_model.dart';
import 'package:location/src/core/data/models/update_geofence_request_model.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/providers/location_repository_provider.dart';
import 'package:location/src/features/location/presentation/state/location_view_state.dart';
import 'package:sf_shared/sf_shared.dart';
import 'package:uuid/uuid.dart';
final locationViewModelProvider =
NotifierProvider.autoDispose<LocationViewModel, LocationViewState>(
LocationViewModel.new,
);
class LocationViewModel extends Notifier<LocationViewState> {
late final LocationRepository _locationRepository;
@override
LocationViewState build() {
_locationRepository = ref.read(locationRepositoryProvider);
final device = ref.watch(selectedDeviceProvider);
if (device != null) {
_fetchData(device.id);
}
return const LocationViewState();
}
Future<void> _fetchData(String deviceId) async {
try {
final results = await Future.wait([
_locationRepository.getGeofences(deviceId: deviceId),
_locationRepository.getFrequentPlaces(deviceId: deviceId),
]);
if (!ref.mounted) return;
state = state.copyWith(
geofences: results[0] as List<GeofenceEntity>,
frequentPlaces: results[1] as List<FrequentPlaceEntity>,
isLoading: false,
);
} catch (e) {
if (!ref.mounted) return;
state = state.copyWith(isLoading: false, errorMessage: _formatError(e));
}
}
Future<bool> createGeofence({
required String name,
String? description,
required double latitude,
required double longitude,
required double radius,
}) async {
state = state.copyWith(isSubmitting: true, errorMessage: '');
try {
final user = await ref.read(userInfoProvider.future);
final device = ref.read(selectedDeviceProvider);
final request = CreateGeofenceRequestModel(
id: const Uuid().v4(),
name: name,
description: description,
latitude: latitude,
longitude: longitude,
radius: radius,
userId: user.delegationId == null ? user.id : null,
delegationId: user.delegationId,
groupId: device?.groupId,
deviceId: device?.id,
);
final created =
await _locationRepository.createGeofence(request: request);
if (!ref.mounted) return false;
state = state.copyWith(
geofences: [...state.geofences, created],
isSubmitting: false,
);
return true;
} catch (e) {
return _handleError(e);
}
}
Future<bool> updateGeofence({
required String id,
required String name,
String? description,
required double latitude,
required double longitude,
required double radius,
}) async {
state = state.copyWith(isSubmitting: true, errorMessage: '');
try {
final request = UpdateGeofenceRequestModel(
id: id,
name: name,
description: description,
latitude: latitude,
longitude: longitude,
radius: radius,
);
final updated =
await _locationRepository.updateGeofence(request: request);
if (!ref.mounted) return false;
state = state.copyWith(
geofences:
state.geofences.map((g) => g.id == id ? updated : g).toList(),
isSubmitting: false,
);
return true;
} catch (e) {
return _handleError(e);
}
}
Future<bool> deleteGeofence({required String id}) async {
state = state.copyWith(errorMessage: '');
try {
await _locationRepository.deleteGeofence(geofenceId: id);
if (!ref.mounted) return false;
state = state.copyWith(
geofences: state.geofences.where((g) => g.id != id).toList(),
);
return true;
} catch (e) {
return _handleError(e);
}
}
Future<bool> createFrequentPlace({
required String name,
required double lat,
required double lng,
List<WifiInfoEntity> wifiList = const [],
}) async {
state = state.copyWith(isSubmitting: true, errorMessage: '');
try {
final user = await ref.read(userInfoProvider.future);
final device = ref.read(selectedDeviceProvider);
final request = CreateFrequentPlaceRequestModel(
id: const Uuid().v4(),
name: name,
lat: lat,
lng: lng,
wifiList: wifiList
.map((w) => WifiInfoResponseModel(
SSID: w.ssid,
BSSID: w.bssid,
signal: w.signal,
))
.toList(),
userId: user.delegationId == null ? user.id : null,
delegationId: user.delegationId,
groupId: device?.groupId,
deviceId: device?.id,
);
final created =
await _locationRepository.createFrequentPlace(request: request);
if (!ref.mounted) return false;
state = state.copyWith(
frequentPlaces: [...state.frequentPlaces, created],
isSubmitting: false,
);
return true;
} catch (e) {
return _handleError(e);
}
}
Future<bool> updateFrequentPlace({
required String id,
required String name,
required double lat,
required double lng,
List<WifiInfoEntity> wifiList = const [],
}) async {
state = state.copyWith(isSubmitting: true, errorMessage: '');
try {
final request = UpdateFrequentPlaceRequestModel(
id: id,
name: name,
lat: lat,
lng: lng,
wifiList: wifiList
.map((w) => WifiInfoResponseModel(
SSID: w.ssid,
BSSID: w.bssid,
signal: w.signal,
))
.toList(),
);
final updated =
await _locationRepository.updateFrequentPlace(request: request);
if (!ref.mounted) return false;
state = state.copyWith(
frequentPlaces:
state.frequentPlaces.map((f) => f.id == id ? updated : f).toList(),
isSubmitting: false,
);
return true;
} catch (e) {
return _handleError(e);
}
}
Future<bool> deleteFrequentPlace({required String id}) async {
state = state.copyWith(errorMessage: '');
try {
await _locationRepository.deleteFrequentPlace(frequentPlaceId: id);
if (!ref.mounted) return false;
state = state.copyWith(
frequentPlaces:
state.frequentPlaces.where((f) => f.id != id).toList(),
);
return true;
} catch (e) {
return _handleError(e);
}
}
Future<void> loadPositionHistory({
required DateTime from,
required DateTime to,
}) async {
final device = ref.read(selectedDeviceProvider);
if (device == null) return;
state = state.copyWith(isLoadingHistory: true, errorMessage: '');
try {
final positions = await _locationRepository.getPositionHistory(
deviceIdentificator: device.identificator,
from: from,
to: to,
);
if (!ref.mounted) return;
state = state.copyWith(
positionHistory: positions,
isLoadingHistory: false,
showRouteTrail: positions.isNotEmpty,
);
} catch (e) {
if (!ref.mounted) return;
state = state.copyWith(
isLoadingHistory: false,
errorMessage: _formatError(e),
);
}
}
void clearPositionHistory() {
state = state.copyWith(
positionHistory: [],
showRouteTrail: false,
);
}
void toggleRouteTrail() {
state = state.copyWith(showRouteTrail: !state.showRouteTrail);
}
bool _handleError(Object e) {
if (!ref.mounted) return false;
state = state.copyWith(
isSubmitting: false,
errorMessage: _formatError(e),
);
return false;
}
String _formatError(Object e) {
final msg = e.toString();
return msg.startsWith('Exception: ') ? msg.substring(11) : msg;
}
}

View File

@@ -0,0 +1,20 @@
import 'package:control_panel/control_panel.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';
@freezed
abstract class LocationViewState with _$LocationViewState {
const factory LocationViewState({
@Default([]) List<GeofenceEntity> geofences,
@Default([]) List<FrequentPlaceEntity> frequentPlaces,
@Default([]) List<PositionEntity> positionHistory,
@Default(true) bool isLoading,
@Default(false) bool isLoadingHistory,
@Default(false) bool isSubmitting,
@Default(false) bool showRouteTrail,
@Default('') String errorMessage,
}) = _LocationViewState;
}

View File

@@ -0,0 +1,310 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// coverage:ignore-file
// 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';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$LocationViewState {
List<GeofenceEntity> get geofences; List<FrequentPlaceEntity> get frequentPlaces; List<PositionEntity> get positionHistory; bool get isLoading; bool get isLoadingHistory; bool get isSubmitting; bool get showRouteTrail; String get errorMessage;
/// Create a copy of LocationViewState
/// 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);
@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.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isLoadingHistory, isLoadingHistory) || other.isLoadingHistory == isLoadingHistory)&&(identical(other.isSubmitting, isSubmitting) || other.isSubmitting == isSubmitting)&&(identical(other.showRouteTrail, showRouteTrail) || other.showRouteTrail == showRouteTrail)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage));
}
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(geofences),const DeepCollectionEquality().hash(frequentPlaces),const DeepCollectionEquality().hash(positionHistory),isLoading,isLoadingHistory,isSubmitting,showRouteTrail,errorMessage);
@override
String toString() {
return 'LocationViewState(geofences: $geofences, frequentPlaces: $frequentPlaces, positionHistory: $positionHistory, isLoading: $isLoading, isLoadingHistory: $isLoadingHistory, isSubmitting: $isSubmitting, showRouteTrail: $showRouteTrail, errorMessage: $errorMessage)';
}
}
/// @nodoc
abstract mixin class $LocationViewStateCopyWith<$Res> {
factory $LocationViewStateCopyWith(LocationViewState value, $Res Function(LocationViewState) _then) = _$LocationViewStateCopyWithImpl;
@useResult
$Res call({
List<GeofenceEntity> geofences, List<FrequentPlaceEntity> frequentPlaces, List<PositionEntity> positionHistory, bool isLoading, bool isLoadingHistory, bool isSubmitting, bool showRouteTrail, String errorMessage
});
}
/// @nodoc
class _$LocationViewStateCopyWithImpl<$Res>
implements $LocationViewStateCopyWith<$Res> {
_$LocationViewStateCopyWithImpl(this._self, this._then);
final LocationViewState _self;
final $Res Function(LocationViewState) _then;
/// Create a copy of LocationViewState
/// 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? isLoading = null,Object? isLoadingHistory = null,Object? isSubmitting = null,Object? showRouteTrail = null,Object? errorMessage = null,}) {
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
as List<FrequentPlaceEntity>,positionHistory: null == positionHistory ? _self.positionHistory : positionHistory // ignore: cast_nullable_to_non_nullable
as List<PositionEntity>,isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable
as bool,isLoadingHistory: null == isLoadingHistory ? _self.isLoadingHistory : isLoadingHistory // ignore: cast_nullable_to_non_nullable
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,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
/// Adds pattern-matching-related methods to [LocationViewState].
extension LocationViewStatePatterns on LocationViewState {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _LocationViewState value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _LocationViewState() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _LocationViewState value) $default,){
final _that = this;
switch (_that) {
case _LocationViewState():
return $default(_that);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _LocationViewState value)? $default,){
final _that = this;
switch (_that) {
case _LocationViewState() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( List<GeofenceEntity> geofences, List<FrequentPlaceEntity> frequentPlaces, List<PositionEntity> positionHistory, bool isLoading, bool isLoadingHistory, bool isSubmitting, bool showRouteTrail, String errorMessage)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _LocationViewState() when $default != null:
return $default(_that.geofences,_that.frequentPlaces,_that.positionHistory,_that.isLoading,_that.isLoadingHistory,_that.isSubmitting,_that.showRouteTrail,_that.errorMessage);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( List<GeofenceEntity> geofences, List<FrequentPlaceEntity> frequentPlaces, List<PositionEntity> positionHistory, bool isLoading, bool isLoadingHistory, bool isSubmitting, bool showRouteTrail, String errorMessage) $default,) {final _that = this;
switch (_that) {
case _LocationViewState():
return $default(_that.geofences,_that.frequentPlaces,_that.positionHistory,_that.isLoading,_that.isLoadingHistory,_that.isSubmitting,_that.showRouteTrail,_that.errorMessage);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( List<GeofenceEntity> geofences, List<FrequentPlaceEntity> frequentPlaces, List<PositionEntity> positionHistory, bool isLoading, bool isLoadingHistory, bool isSubmitting, bool showRouteTrail, String errorMessage)? $default,) {final _that = this;
switch (_that) {
case _LocationViewState() when $default != null:
return $default(_that.geofences,_that.frequentPlaces,_that.positionHistory,_that.isLoading,_that.isLoadingHistory,_that.isSubmitting,_that.showRouteTrail,_that.errorMessage);case _:
return null;
}
}
}
/// @nodoc
class _LocationViewState implements LocationViewState {
const _LocationViewState({final List<GeofenceEntity> geofences = const [], final List<FrequentPlaceEntity> frequentPlaces = const [], final List<PositionEntity> positionHistory = const [], this.isLoading = true, this.isLoadingHistory = false, this.isSubmitting = false, this.showRouteTrail = false, this.errorMessage = ''}): _geofences = geofences,_frequentPlaces = frequentPlaces,_positionHistory = positionHistory;
final List<GeofenceEntity> _geofences;
@override@JsonKey() List<GeofenceEntity> get geofences {
if (_geofences is EqualUnmodifiableListView) return _geofences;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_geofences);
}
final List<FrequentPlaceEntity> _frequentPlaces;
@override@JsonKey() List<FrequentPlaceEntity> get frequentPlaces {
if (_frequentPlaces is EqualUnmodifiableListView) return _frequentPlaces;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_frequentPlaces);
}
final List<PositionEntity> _positionHistory;
@override@JsonKey() List<PositionEntity> get positionHistory {
if (_positionHistory is EqualUnmodifiableListView) return _positionHistory;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_positionHistory);
}
@override@JsonKey() final bool isLoading;
@override@JsonKey() final bool isLoadingHistory;
@override@JsonKey() final bool isSubmitting;
@override@JsonKey() final bool showRouteTrail;
@override@JsonKey() final String errorMessage;
/// Create a copy of LocationViewState
/// 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);
@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.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isLoadingHistory, isLoadingHistory) || other.isLoadingHistory == isLoadingHistory)&&(identical(other.isSubmitting, isSubmitting) || other.isSubmitting == isSubmitting)&&(identical(other.showRouteTrail, showRouteTrail) || other.showRouteTrail == showRouteTrail)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage));
}
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_geofences),const DeepCollectionEquality().hash(_frequentPlaces),const DeepCollectionEquality().hash(_positionHistory),isLoading,isLoadingHistory,isSubmitting,showRouteTrail,errorMessage);
@override
String toString() {
return 'LocationViewState(geofences: $geofences, frequentPlaces: $frequentPlaces, positionHistory: $positionHistory, isLoading: $isLoading, isLoadingHistory: $isLoadingHistory, isSubmitting: $isSubmitting, showRouteTrail: $showRouteTrail, errorMessage: $errorMessage)';
}
}
/// @nodoc
abstract mixin class _$LocationViewStateCopyWith<$Res> implements $LocationViewStateCopyWith<$Res> {
factory _$LocationViewStateCopyWith(_LocationViewState value, $Res Function(_LocationViewState) _then) = __$LocationViewStateCopyWithImpl;
@override @useResult
$Res call({
List<GeofenceEntity> geofences, List<FrequentPlaceEntity> frequentPlaces, List<PositionEntity> positionHistory, bool isLoading, bool isLoadingHistory, bool isSubmitting, bool showRouteTrail, String errorMessage
});
}
/// @nodoc
class __$LocationViewStateCopyWithImpl<$Res>
implements _$LocationViewStateCopyWith<$Res> {
__$LocationViewStateCopyWithImpl(this._self, this._then);
final _LocationViewState _self;
final $Res Function(_LocationViewState) _then;
/// Create a copy of LocationViewState
/// 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? isLoading = null,Object? isLoadingHistory = null,Object? isSubmitting = null,Object? showRouteTrail = null,Object? errorMessage = null,}) {
return _then(_LocationViewState(
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
as List<PositionEntity>,isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable
as bool,isLoadingHistory: null == isLoadingHistory ? _self.isLoadingHistory : isLoadingHistory // ignore: cast_nullable_to_non_nullable
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,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
// dart format on

View File

@@ -0,0 +1,290 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:latlong2/latlong.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;
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(const 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 theme = ref.watch(themePortProvider);
final primaryColor = theme.getColorFor(ThemeCode.legacyPrimary);
final isSubmitting = ref.watch(
locationViewModelProvider.select((s) => s.isSubmitting),
);
final errorMessage = ref.watch(
locationViewModelProvider.select((s) => s.errorMessage),
);
return DraggableScrollableSheet(
initialChildSize: 0.25,
minChildSize: 0.15,
maxChildSize: 0.7,
builder: (context, scrollController) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
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: Colors.grey.shade300,
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),
),
),
const SizedBox(width: 8),
GestureDetector(
onTap: () => _removeWifi(i),
child: Icon(Icons.remove_circle_outline,
color: Colors.grey.shade500, size: 22),
),
],
),
);
}),
],
if (errorMessage.isNotEmpty)
Padding(
padding: const EdgeInsets.only(top: 8),
child: Text(
errorMessage,
style:
const TextStyle(color: Colors.red, fontSize: 13),
),
),
SizedBox(height: SizeUtils.getByScreen(small: 8, big: 10)),
],
),
);
},
);
}
}

View File

@@ -0,0 +1,271 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.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: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;
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 theme = ref.watch(themePortProvider);
final primaryColor = theme.getColorFor(ThemeCode.legacyPrimary);
final isSubmitting = ref.watch(
locationViewModelProvider.select((s) => s.isSubmitting),
);
final errorMessage = ref.watch(
locationViewModelProvider.select((s) => s.errorMessage),
);
return DraggableScrollableSheet(
initialChildSize: 0.35,
minChildSize: 0.15,
maxChildSize: 0.7,
builder: (context, scrollController) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
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: Colors.grey.shade300,
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 (errorMessage.isNotEmpty)
Padding(
padding: const EdgeInsets.only(top: 8),
child: Text(
errorMessage,
style: const TextStyle(color: Colors.red, fontSize: 13),
),
),
SizedBox(height: SizeUtils.getByScreen(small: 8, big: 10)),
],
),
);
},
);
}
}

View File

@@ -0,0 +1,265 @@
import 'package:control_panel/control_panel.dart';
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:sf_shared/sf_shared.dart';
import 'package:utils/utils.dart';
class DeviceBanner extends ConsumerStatefulWidget {
final DeviceEntity device;
final PositionEntity? position;
final List<DeviceEntity> devices;
final ValueChanged<DeviceEntity> onDeviceChanged;
const DeviceBanner({
super.key,
required this.device,
required this.position,
required this.devices,
required this.onDeviceChanged,
});
@override
ConsumerState<DeviceBanner> createState() => _DeviceBannerState();
}
class _DeviceBannerState extends ConsumerState<DeviceBanner> {
late final PageController _pageController;
int _currentPage = 0;
@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;
_pageController.animateToPage(
newIndex,
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
);
}
}
@override
void dispose() {
_pageController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final theme = ref.read(themePortProvider);
final primaryColor = theme.getColorFor(ThemeCode.legacyPrimary);
return Container(
width: SizeUtils.getByScreen(small: 340, big: 338),
margin: EdgeInsets.only(
bottom: SizeUtils.getByScreen(small: 16, big: 14),
),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.1),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
height: 72,
child: PageView.builder(
controller: _pageController,
itemCount: widget.devices.length,
onPageChanged: (index) {
setState(() => _currentPage = index);
widget.onDeviceChanged(widget.devices[index]);
},
itemBuilder: (context, index) {
final dev = widget.devices[index];
final isSelected = dev.id == widget.device.id;
final pos = isSelected ? widget.position : null;
return _DeviceCard(
device: dev,
position: pos,
primaryColor: primaryColor,
);
},
),
),
if (widget.devices.length > 1)
Padding(
padding: const EdgeInsets.only(bottom: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(
widget.devices.length,
(i) => AnimatedContainer(
duration: const Duration(milliseconds: 200),
width: i == _currentPage ? 18 : 6,
height: 6,
margin: const EdgeInsets.symmetric(horizontal: 3),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(3),
color: i == _currentPage
? primaryColor
: Colors.grey.shade300,
),
),
),
),
),
],
),
);
}
}
class _DeviceCard extends StatelessWidget {
final DeviceEntity device;
final PositionEntity? position;
final Color primaryColor;
const _DeviceCard({
required this.device,
required this.position,
required this.primaryColor,
});
@override
Widget build(BuildContext context) {
final name = device.carrierName;
final deviceName =
name != null && name.isNotEmpty ? name : device.identificator;
final initial = deviceName.isNotEmpty ? deviceName[0].toUpperCase() : '?';
final addressText = position != null
? [
position!.address?.street,
position!.address?.province,
].whereType<String>().where((s) => s.isNotEmpty).join(', ')
: '';
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
child: Row(
children: [
Container(
width: 42,
height: 42,
decoration: BoxDecoration(
color: primaryColor.withValues(alpha: 0.12),
shape: BoxShape.circle,
),
child: Center(
child: Text(
initial,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w700,
color: primaryColor,
),
),
),
),
const SizedBox(width: 10),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
deviceName,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w600,
color: Colors.grey.shade800,
),
overflow: TextOverflow.ellipsis,
),
if (addressText.isNotEmpty)
Padding(
padding: const EdgeInsets.only(top: 2),
child: Row(
children: [
Icon(Icons.location_on,
size: 12, color: Colors.grey.shade400),
const SizedBox(width: 3),
Expanded(
child: Text(
addressText,
style: TextStyle(
fontSize: 11,
color: Colors.grey.shade500,
),
overflow: TextOverflow.ellipsis,
),
),
],
),
),
],
),
),
if (position != null || device.battery != null)
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
if (device.battery != null)
Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
toBatteryIcon(device.battery!),
size: 16,
color: device.battery! > 20
? primaryColor
: Colors.orange,
),
const SizedBox(width: 3),
Text(
'${device.battery}%',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
color: device.battery! > 20
? primaryColor
: Colors.orange,
),
),
],
),
if (position != null)
Padding(
padding: const EdgeInsets.only(top: 3),
child: Text(
formatPositionDate(position!.positionDate),
style: TextStyle(
fontSize: 10,
color: Colors.grey.shade400,
),
),
),
],
),
],
),
);
}
}

View File

@@ -0,0 +1,23 @@
import 'package:flutter/material.dart';
InputDecoration locationInputDecoration({
required String hintText,
required Color primaryColor,
}) {
return InputDecoration(
hintText: hintText,
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12)),
borderSide: BorderSide(color: Colors.grey.shade300),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12)),
borderSide: BorderSide(color: Colors.grey.shade300),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12)),
borderSide: BorderSide(color: primaryColor, width: 2),
),
contentPadding: EdgeInsets.symmetric(horizontal: 14, vertical: 14),
);
}

View File

@@ -0,0 +1,546 @@
import 'package:control_panel/control_panel.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';
import 'package:latlong2/latlong.dart';
import 'package:legacy_shared/legacy_shared.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:sf_localizations/sf_localizations.dart';
import 'package:sf_shared/sf_shared.dart';
import 'package:utils/utils.dart';
import 'device_banner.dart';
import 'name_input_sheet.dart';
import 'map_controls/layer_toggles.dart';
import 'map_controls/map_action_button.dart';
import 'map_controls/map_style_selector.dart';
import 'map_controls/placement_banner.dart';
import 'map_controls/radius_slider_bar.dart';
import 'map_info_cards/frequent_place_info_card.dart';
import 'map_info_cards/geofence_info_card.dart';
import 'map_info_cards/history_position_info_card.dart';
import 'modal_overlay.dart';
const _defaultCenter = LatLng(40.4168, -3.7038);
const _defaultZoom = 15.0;
class LocationMap extends ConsumerStatefulWidget {
final PositionEntity? selectedPosition;
final DeviceEntity? selectedDevice;
final List<DeviceEntity> devices;
final List<GeofenceEntity> geofences;
final List<FrequentPlaceEntity> frequentPlaces;
final List<PositionEntity> positionHistory;
final bool showRouteTrail;
final bool isLoadingHistory;
final ValueChanged<DeviceEntity> onDeviceChanged;
final VoidCallback onRefreshPosition;
const LocationMap({
super.key,
required this.selectedPosition,
required this.selectedDevice,
required this.devices,
required this.geofences,
required this.frequentPlaces,
required this.positionHistory,
required this.showRouteTrail,
required this.isLoadingHistory,
required this.onDeviceChanged,
required this.onRefreshPosition,
});
@override
ConsumerState<LocationMap> createState() => _LocationMapState();
}
class _LocationMapState extends ConsumerState<LocationMap> {
late final MapController _mapController;
LocationMapViewModel get _vm =>
ref.read(locationMapViewModelProvider.notifier);
@override
void initState() {
super.initState();
_mapController = MapController();
}
@override
void dispose() {
_mapController.dispose();
super.dispose();
}
@override
void didUpdateWidget(LocationMap oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.selectedPosition != null &&
widget.selectedPosition != oldWidget.selectedPosition) {
_centerOnDevice();
}
}
void _centerOnDevice() {
if (widget.selectedPosition == null) return;
_mapController.move(
LatLng(
widget.selectedPosition!.latitude,
widget.selectedPosition!.longitude,
),
_defaultZoom,
);
}
void _confirmPlacement() {
final center = _mapController.camera.center;
final mapState = ref.read(locationMapViewModelProvider);
if (mapState.placingMode == PlacingMode.geofence) {
_vm.confirmGeofencePlacement(center);
} else {
_vm.confirmFrequentPlacePlacement();
showNameInputSheet(
context,
ref: ref,
title: context.translate(I18n.locationNewFrequentPlace),
hintText: context.translate(I18n.locationHintFrequentPlace),
onSubmit: (name, _) => ref
.read(locationViewModelProvider.notifier)
.createFrequentPlace(
name: name, lat: center.latitude, lng: center.longitude),
);
}
}
void _confirmRadius() {
final mapState = ref.read(locationMapViewModelProvider);
final point = mapState.previewPoint!;
final radius = mapState.previewRadius;
final editing = mapState.editingGeofence;
_vm.confirmRadius();
showNameInputSheet(
context,
ref: ref,
title: editing != null
? context.translate(I18n.locationEditGeofence)
: context.translate(I18n.locationNewGeofence),
hintText: context.translate(I18n.locationHintGeofence),
initialName: editing?.name,
initialDescription: editing?.description,
showDescription: true,
submitLabel: editing != null
? context.translate(I18n.locationSave)
: context.translate(I18n.locationCreate),
onSubmit: (name, description) {
if (editing != null) {
return ref.read(locationViewModelProvider.notifier).updateGeofence(
id: editing.id,
name: name,
description: description,
latitude: point.latitude,
longitude: point.longitude,
radius: radius,
);
}
return ref.read(locationViewModelProvider.notifier).createGeofence(
name: name,
description: description,
latitude: point.latitude,
longitude: point.longitude,
radius: radius,
);
},
).then((_) => _vm.clearPreviewPoint());
}
void _handleHistoryTap() {
if (widget.positionHistory.isEmpty) {
_openDateRangePicker();
} else {
ref.read(locationViewModelProvider.notifier).toggleRouteTrail();
}
}
Future<void> _openDateRangePicker() async {
final primaryColor =
ref.read(themePortProvider).getColorFor(ThemeCode.legacyPrimary);
final now = DateTime.now();
final picked = await showDateRangePicker(
context: context,
firstDate: now.subtract(const Duration(days: 365)),
lastDate: now,
initialDateRange: DateTimeRange(
start: now.subtract(const Duration(days: 1)),
end: now,
),
builder: (context, child) => Theme(
data: Theme.of(context).copyWith(
colorScheme: ColorScheme.light(primary: primaryColor),
),
child: child!,
),
);
if (picked != null) {
final to = DateTime(
picked.end.year, picked.end.month, picked.end.day, 23, 59, 59);
ref
.read(locationViewModelProvider.notifier)
.loadPositionHistory(from: picked.start, to: to);
}
}
void _onEditFrequentPlace(FrequentPlaceEntity fp) {
_vm.clearSelectedFrequentPlace();
showNameInputSheet(
context,
ref: ref,
title: context.translate(I18n.locationEditFrequentPlace),
hintText: context.translate(I18n.locationHintFrequentPlace),
initialName: fp.name,
submitLabel: context.translate(I18n.locationSave),
onSubmit: (name, _) => ref
.read(locationViewModelProvider.notifier)
.updateFrequentPlace(
id: fp.id, name: name, lat: fp.lat, lng: fp.lng, wifiList: fp.wifiList),
);
}
Marker _buildHistoryMarker({
required PositionEntity position,
required IconData icon,
required Color color,
}) {
return Marker(
point: LatLng(position.latitude, position.longitude),
width: 24,
height: 24,
child: GestureDetector(
onTap: () => _vm.selectHistoryPosition(position),
child: Container(
decoration: BoxDecoration(
color: color,
shape: BoxShape.circle,
border: Border.all(color: Colors.white, width: 2),
),
child: Icon(icon, color: Colors.white, size: 14),
),
),
rotate: true,
);
}
List<Widget> _buildMapLayers(LocationMapViewState mapState, Color primaryColor) {
return [
TileLayer(
urlTemplate: ref.watch(mapStyleProvider).urlTemplate,
userAgentPackageName: 'com.savefamily.sf_platform',
),
if (mapState.showGeofences)
CircleLayer(
circles: widget.geofences
.where((g) => g.isActive)
.map((g) => CircleMarker(
point: LatLng(g.latitude, g.longitude),
radius: g.radius,
useRadiusInMeter: true,
color: Colors.blue.withValues(alpha: 0.15),
borderColor: Colors.blue.withValues(alpha: 0.7),
borderStrokeWidth: 2,
))
.toList(),
),
if (widget.showRouteTrail && widget.positionHistory.isNotEmpty)
PolylineLayer(
polylines: [
Polyline(
points: widget.positionHistory
.map((p) => LatLng(p.latitude, p.longitude))
.toList(),
color: Colors.purple,
strokeWidth: 3.0,
),
],
),
if (mapState.previewPoint != null)
CircleLayer(
circles: [
CircleMarker(
point: mapState.previewPoint!,
radius: mapState.previewRadius,
useRadiusInMeter: true,
color: primaryColor.withValues(alpha: 0.2),
borderColor: primaryColor.withValues(alpha: 0.8),
borderStrokeWidth: 2,
),
],
),
MarkerLayer(markers: _buildMarkers(mapState, primaryColor)),
if (widget.selectedDevice != null)
Align(
alignment: Alignment.bottomCenter,
child: DeviceBanner(
device: widget.selectedDevice!,
position: widget.selectedPosition,
devices: widget.devices,
onDeviceChanged: widget.onDeviceChanged,
),
),
];
}
List<Marker> _buildMarkers(LocationMapViewState mapState, Color primaryColor) {
return [
if (mapState.previewPoint != null)
Marker(
point: mapState.previewPoint!,
width: 40,
height: 40,
child: Icon(Icons.add_location_alt, color: primaryColor, size: 36),
rotate: true,
),
if (widget.showRouteTrail && widget.positionHistory.length == 1)
_buildHistoryMarker(
position: widget.positionHistory.first,
icon: Icons.location_on,
color: Colors.purple,
),
if (widget.showRouteTrail && widget.positionHistory.length >= 2) ...[
_buildHistoryMarker(
position: widget.positionHistory.first,
icon: Icons.play_arrow,
color: Colors.purple,
),
_buildHistoryMarker(
position: widget.positionHistory.last,
icon: Icons.stop,
color: Colors.purple.shade800,
),
],
if (widget.selectedPosition != null)
Marker(
point: LatLng(
widget.selectedPosition!.latitude,
widget.selectedPosition!.longitude,
),
width: 100,
height: 100,
child: PulsingLocationMarker(color: primaryColor),
rotate: true,
),
if (mapState.showFrequentPlaces)
...widget.frequentPlaces.map(
(fp) => Marker(
point: LatLng(fp.lat, fp.lng),
width: 40,
height: 40,
child: GestureDetector(
onLongPress: () => _vm.selectFrequentPlace(fp),
child: Container(
decoration: BoxDecoration(
color: Colors.orange.withValues(alpha: 0.3),
shape: BoxShape.circle,
border: Border.all(
color: Colors.orange.withValues(alpha: 0.7), width: 2),
),
child: const Icon(Icons.home_rounded,
color: Colors.orange, size: 20),
),
),
rotate: true,
),
),
if (mapState.showGeofences)
...widget.geofences.where((g) => g.isActive).map(
(g) => Marker(
point: LatLng(g.latitude, g.longitude),
width: 36,
height: 36,
child: GestureDetector(
onLongPress: () => _vm.selectGeofence(g),
child: Container(
decoration: BoxDecoration(
color: Colors.blue.withValues(alpha: 0.3),
shape: BoxShape.circle,
border: Border.all(
color: Colors.blue.withValues(alpha: 0.7), width: 2),
),
child: const Icon(Icons.shield, color: Colors.blue, size: 18),
),
),
rotate: true,
),
),
];
}
List<Widget> _buildControls(
LocationMapViewState mapState, Color primaryColor) {
if (mapState.placingMode != PlacingMode.none) {
return [
Center(
child: Icon(Icons.add_circle_outline, size: 48, color: primaryColor),
),
Positioned(
top: 12,
left: 12,
right: 12,
child: PlacementBanner(
onCancel: _vm.cancelPlacing,
onConfirm: _confirmPlacement,
),
),
];
}
if (mapState.adjustingRadius) {
return [
Positioned(
bottom: SizeUtils.getByScreen(small: 100, big: 94),
left: 12,
right: 12,
child: RadiusSliderBar(
radius: mapState.previewRadius,
primaryColor: primaryColor,
onChanged: _vm.updatePreviewRadius,
onCancel: _vm.cancelPlacing,
onConfirm: _confirmRadius,
),
),
];
}
return [
Positioned(
top: 12,
left: 12,
child: const MapStyleSelector(),
),
Positioned(
top: 12,
right: 12,
child: LayerToggles(
showGeofences: mapState.showGeofences,
showFrequentPlaces: mapState.showFrequentPlaces,
showRouteTrail: widget.showRouteTrail,
hasPositionHistory: widget.positionHistory.isNotEmpty,
isLoadingHistory: widget.isLoadingHistory,
onGeofencesToggled: _vm.toggleGeofences,
onFrequentPlacesToggled: _vm.toggleFrequentPlaces,
onHistoryTapped: _handleHistoryTap,
onHistoryLongPressed: _openDateRangePicker,
),
),
Positioned(
bottom: SizeUtils.getByScreen(small: 120, big: 110),
right: 12,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
MapActionButton(
icon: Icons.add_location_alt,
onTap: () => _vm.startPlacing(PlacingMode.geofence),
),
const SizedBox(height: 8),
MapActionButton(
icon: Icons.add_home,
onTap: () => _vm.startPlacing(PlacingMode.frequentPlace),
),
const SizedBox(height: 8),
MapActionButton(
icon: Icons.refresh,
onTap: widget.onRefreshPosition,
),
if (widget.selectedPosition != null) ...[
const SizedBox(height: 8),
MapActionButton(
icon: Icons.my_location,
onTap: _centerOnDevice,
),
],
],
),
),
];
}
List<Widget> _buildInfoCards(LocationMapViewState mapState) {
return [
if (mapState.selectedGeofence != null)
ModalOverlay(
onDismiss: _vm.clearSelectedGeofence,
child: GeofenceInfoCard(
geofence: mapState.selectedGeofence!,
onClose: _vm.clearSelectedGeofence,
onEdit: () =>
_vm.startEditingGeofence(mapState.selectedGeofence!),
onDelete: () {
final id = mapState.selectedGeofence!.id;
_vm.clearSelectedGeofence();
ref.read(locationViewModelProvider.notifier).deleteGeofence(id: id);
},
),
),
if (mapState.selectedFrequentPlace != null)
ModalOverlay(
onDismiss: _vm.clearSelectedFrequentPlace,
child: FrequentPlaceInfoCard(
frequentPlace: mapState.selectedFrequentPlace!,
onClose: _vm.clearSelectedFrequentPlace,
onEdit: () => _onEditFrequentPlace(mapState.selectedFrequentPlace!),
onDelete: () {
final id = mapState.selectedFrequentPlace!.id;
_vm.clearSelectedFrequentPlace();
ref.read(locationViewModelProvider.notifier).deleteFrequentPlace(id: id);
},
),
),
if (mapState.selectedHistoryPosition != null)
ModalOverlay(
onDismiss: _vm.clearSelectedHistoryPosition,
child: HistoryPositionInfoCard(
position: mapState.selectedHistoryPosition!,
onClose: _vm.clearSelectedHistoryPosition,
),
),
];
}
@override
Widget build(BuildContext context) {
final mapState = ref.watch(locationMapViewModelProvider);
final primaryColor =
ref.read(themePortProvider).getColorFor(ThemeCode.legacyPrimary);
final initialCenter = widget.selectedPosition != null
? LatLng(
widget.selectedPosition!.latitude,
widget.selectedPosition!.longitude,
)
: _defaultCenter;
return Stack(
children: [
FlutterMap(
mapController: _mapController,
options: MapOptions(
initialCenter: initialCenter,
initialZoom: _defaultZoom,
minZoom: 11,
keepAlive: true,
),
children: _buildMapLayers(mapState, primaryColor),
),
..._buildControls(mapState, primaryColor),
..._buildInfoCards(mapState),
],
);
}
}

View File

@@ -0,0 +1,126 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:sf_localizations/sf_localizations.dart';
class LayerToggles extends ConsumerWidget {
final bool showGeofences;
final bool showFrequentPlaces;
final bool showRouteTrail;
final bool hasPositionHistory;
final bool isLoadingHistory;
final VoidCallback onGeofencesToggled;
final VoidCallback onFrequentPlacesToggled;
final VoidCallback onHistoryTapped;
final VoidCallback onHistoryLongPressed;
const LayerToggles({
super.key,
required this.showGeofences,
required this.showFrequentPlaces,
required this.showRouteTrail,
required this.hasPositionHistory,
required this.isLoadingHistory,
required this.onGeofencesToggled,
required this.onFrequentPlacesToggled,
required this.onHistoryTapped,
required this.onHistoryLongPressed,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
_LayerChip(
icon: Icons.circle_outlined,
label: context.translate(I18n.locationLayerGeofences),
color: Colors.blue,
isActive: showGeofences,
onTap: onGeofencesToggled,
),
const SizedBox(height: 6),
_LayerChip(
icon: Icons.home_rounded,
label: context.translate(I18n.locationLayerFrequentPlaces),
color: Colors.orange,
isActive: showFrequentPlaces,
onTap: onFrequentPlacesToggled,
),
const SizedBox(height: 6),
_LayerChip(
icon: isLoadingHistory ? Icons.hourglass_top : Icons.route,
label: context.translate(I18n.locationLayerHistory),
color: Colors.purple,
isActive: showRouteTrail && hasPositionHistory,
onTap: onHistoryTapped,
onLongPress: hasPositionHistory ? onHistoryLongPressed : null,
),
],
);
}
}
class _LayerChip extends StatelessWidget {
final IconData icon;
final String label;
final Color color;
final bool isActive;
final VoidCallback onTap;
final VoidCallback? onLongPress;
const _LayerChip({
required this.icon,
required this.label,
required this.color,
required this.isActive,
required this.onTap,
this.onLongPress,
});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
onLongPress: onLongPress,
child: AnimatedContainer(
duration: const Duration(milliseconds: 200),
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
decoration: BoxDecoration(
color: isActive ? color : Colors.white,
borderRadius: BorderRadius.circular(20),
border: Border.all(
color: isActive ? color : Colors.grey.shade400,
width: 1.5,
),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.12),
blurRadius: 4,
offset: const Offset(0, 2),
),
],
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
icon,
size: 16,
color: isActive ? Colors.white : Colors.grey.shade600,
),
const SizedBox(width: 5),
Text(
label,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
color: isActive ? Colors.white : Colors.grey.shade600,
),
),
],
),
),
);
}
}

View File

@@ -0,0 +1,38 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class MapActionButton extends ConsumerWidget {
final IconData icon;
final VoidCallback onTap;
const MapActionButton({
super.key,
required this.icon,
required this.onTap,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
final theme = ref.read(themePortProvider);
return Material(
color: theme.getColorFor(ThemeCode.backgroundPrimary),
borderRadius: BorderRadius.circular(8),
elevation: 2,
child: InkWell(
onTap: onTap,
borderRadius: BorderRadius.circular(8),
child: SizedBox(
width: 40,
height: 40,
child: Icon(
icon,
size: 24,
color: theme.getColorFor(ThemeCode.legacyPrimary),
),
),
),
);
}
}

View File

@@ -0,0 +1,100 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:legacy_shared/legacy_shared.dart';
import 'package:sf_localizations/sf_localizations.dart';
const _labelKeys = {
MapStyle.standard: I18n.locationMapStyleStandard,
MapStyle.voyager: I18n.locationMapStyleVoyager,
MapStyle.light: I18n.locationMapStyleLight,
MapStyle.dark: I18n.locationMapStyleDark,
MapStyle.satellite: I18n.locationMapStyleSatellite,
};
class MapStyleSelector extends ConsumerStatefulWidget {
const MapStyleSelector({super.key});
@override
ConsumerState<MapStyleSelector> createState() => _MapStyleSelectorState();
}
class _MapStyleSelectorState extends ConsumerState<MapStyleSelector> {
bool _expanded = false;
@override
Widget build(BuildContext context) {
final currentStyle = ref.watch(mapStyleProvider);
final theme = ref.read(themePortProvider);
final primaryColor = theme.getColorFor(ThemeCode.legacyPrimary);
if (!_expanded) {
return Material(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
elevation: 2,
child: InkWell(
onTap: () => setState(() => _expanded = true),
borderRadius: BorderRadius.circular(8),
child: const SizedBox(
width: 40,
height: 40,
child: Icon(Icons.layers, size: 22, color: Colors.grey),
),
),
);
}
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.15),
blurRadius: 6,
offset: const Offset(0, 2),
),
],
),
padding: const EdgeInsets.symmetric(vertical: 6),
child: Column(
mainAxisSize: MainAxisSize.min,
children: MapStyle.values.map((style) {
final isSelected = style == currentStyle;
return InkWell(
onTap: () {
ref.read(mapStyleProvider.notifier).setStyle(style);
setState(() => _expanded = false);
},
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
style == MapStyle.satellite
? Icons.satellite_alt
: Icons.map,
size: 16,
color: isSelected ? primaryColor : Colors.grey.shade600,
),
const SizedBox(width: 8),
Text(
context.translate(_labelKeys[style]!),
style: TextStyle(
fontSize: 13,
fontWeight:
isSelected ? FontWeight.w600 : FontWeight.w400,
color: isSelected ? primaryColor : Colors.grey.shade700,
),
),
],
),
),
);
}).toList(),
),
);
}
}

View File

@@ -0,0 +1,78 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:sf_localizations/sf_localizations.dart';
class PlacementBanner extends ConsumerWidget {
final VoidCallback onCancel;
final VoidCallback onConfirm;
const PlacementBanner({
super.key,
required this.onCancel,
required this.onConfirm,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
final primaryColor = ref.read(themePortProvider).getColorFor(ThemeCode.legacyPrimary);
return Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.15),
blurRadius: 6,
offset: const Offset(0, 2),
),
],
),
child: Row(
children: [
GestureDetector(
onTap: onCancel,
child: Container(
padding: const EdgeInsets.all(6),
decoration: BoxDecoration(
color: Colors.grey.shade200,
shape: BoxShape.circle,
),
child: Icon(Icons.close, size: 20, color: Colors.grey.shade700),
),
),
const SizedBox(width: 12),
Expanded(
child: Text(
context.translate(I18n.locationPlacementHint),
style: const TextStyle(
fontSize: 13,
fontWeight: FontWeight.w500,
),
),
),
const SizedBox(width: 12),
GestureDetector(
onTap: onConfirm,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8),
decoration: BoxDecoration(
color: primaryColor,
borderRadius: BorderRadius.circular(20),
),
child: Text(
context.translate(I18n.locationConfirm),
style: const TextStyle(
color: Colors.white,
fontSize: 13,
fontWeight: FontWeight.w600,
),
),
),
),
],
),
);
}
}

View File

@@ -0,0 +1,95 @@
import 'package:flutter/material.dart';
import 'package:sf_localizations/sf_localizations.dart';
class RadiusSliderBar extends StatelessWidget {
final double radius;
final Color primaryColor;
final ValueChanged<double> onChanged;
final VoidCallback onCancel;
final VoidCallback onConfirm;
const RadiusSliderBar({
super.key,
required this.radius,
required this.primaryColor,
required this.onChanged,
required this.onCancel,
required this.onConfirm,
});
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.15),
blurRadius: 6,
offset: const Offset(0, 2),
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
GestureDetector(
onTap: onCancel,
child: Container(
padding: const EdgeInsets.all(4),
decoration: BoxDecoration(
color: Colors.grey.shade200,
shape: BoxShape.circle,
),
child: Icon(Icons.close, size: 18, color: Colors.grey.shade700),
),
),
const SizedBox(width: 8),
Expanded(
child: Text(
'${context.translate(I18n.locationRadius)}: ${context.translate(I18n.locationRadiusMeters, args: {'radius': '${radius.round()}'})}',
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.w600,
),
),
),
GestureDetector(
onTap: onConfirm,
child: Container(
padding:
const EdgeInsets.symmetric(horizontal: 14, vertical: 6),
decoration: BoxDecoration(
color: primaryColor,
borderRadius: BorderRadius.circular(20),
),
child: Text(
context.translate(I18n.locationConfirm),
style: const TextStyle(
color: Colors.white,
fontSize: 13,
fontWeight: FontWeight.w600,
),
),
),
),
],
),
Slider(
value: radius,
min: 50,
max: 2000,
divisions: 39,
activeColor: primaryColor,
label: '${radius.round()} m',
onChanged: onChanged,
),
],
),
);
}
}

View File

@@ -0,0 +1,39 @@
import 'package:flutter/material.dart';
import 'package:location/src/core/domain/entities/frequent_place_entity.dart';
import 'package:sf_localizations/sf_localizations.dart';
import 'map_info_card.dart';
class FrequentPlaceInfoCard extends StatelessWidget {
final FrequentPlaceEntity frequentPlace;
final VoidCallback onClose;
final VoidCallback onEdit;
final VoidCallback onDelete;
const FrequentPlaceInfoCard({
super.key,
required this.frequentPlace,
required this.onClose,
required this.onEdit,
required this.onDelete,
});
@override
Widget build(BuildContext context) {
return MapItemInfoCard(
icon: Icons.home_rounded,
iconColor: Colors.orange,
title: frequentPlace.name,
onClose: onClose,
onEdit: onEdit,
onDelete: onDelete,
content: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
infoRow(Icons.location_on_outlined, context.translate(I18n.locationCoordinates),
'${frequentPlace.lat.toStringAsFixed(4)}, ${frequentPlace.lng.toStringAsFixed(4)}'),
],
),
);
}
}

View File

@@ -0,0 +1,63 @@
import 'package:design_system/design_system.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:sf_localizations/sf_localizations.dart';
import 'map_info_card.dart';
class GeofenceInfoCard extends ConsumerWidget {
final GeofenceEntity geofence;
final VoidCallback onClose;
final VoidCallback onEdit;
final VoidCallback onDelete;
const GeofenceInfoCard({
super.key,
required this.geofence,
required this.onClose,
required this.onEdit,
required this.onDelete,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
final primaryColor =
ref.read(themePortProvider).getColorFor(ThemeCode.legacyPrimary);
return MapItemInfoCard(
icon: Icons.shield,
iconColor: Colors.blue,
title: geofence.name,
onClose: onClose,
onEdit: onEdit,
onDelete: onDelete,
content: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (geofence.description != null &&
geofence.description!.isNotEmpty) ...[
Text(
geofence.description!,
style: TextStyle(fontSize: 13, color: Colors.grey.shade600),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
const SizedBox(height: 8),
],
infoRow(Icons.radio_button_checked, context.translate(I18n.locationRadius),
context.translate(I18n.locationRadiusMeters, args: {'radius': '${geofence.radius.round()}'})),
const SizedBox(height: 6),
infoRow(Icons.location_on_outlined, context.translate(I18n.locationCoordinates),
'${geofence.latitude.toStringAsFixed(4)}, ${geofence.longitude.toStringAsFixed(4)}'),
const SizedBox(height: 6),
infoRow(
geofence.isActive ? Icons.check_circle : Icons.cancel,
context.translate(I18n.locationStatus),
geofence.isActive ? context.translate(I18n.locationStatusActive) : context.translate(I18n.locationStatusInactive),
iconColor: geofence.isActive ? primaryColor : Colors.grey,
),
],
),
);
}
}

View File

@@ -0,0 +1,60 @@
import 'package:control_panel/control_panel.dart';
import 'package:flutter/material.dart';
import 'package:sf_localizations/sf_localizations.dart';
import 'map_info_card.dart';
class HistoryPositionInfoCard extends StatelessWidget {
final PositionEntity position;
final VoidCallback onClose;
const HistoryPositionInfoCard({
super.key,
required this.position,
required this.onClose,
});
@override
Widget build(BuildContext context) {
final date = DateTime.fromMillisecondsSinceEpoch(position.positionDate);
final dateStr =
'${date.day.toString().padLeft(2, '0')}/${date.month.toString().padLeft(2, '0')}/${date.year} '
'${date.hour.toString().padLeft(2, '0')}:${date.minute.toString().padLeft(2, '0')}';
final addressParts = [
position.address?.street,
position.address?.city,
position.address?.province,
].whereType<String>().where((s) => s.isNotEmpty).toList();
return ReadOnlyInfoCard(
icon: Icons.route,
iconColor: Colors.purple,
title: context.translate(I18n.locationHistoryPosition),
onClose: onClose,
content: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
infoRow(Icons.access_time, context.translate(I18n.locationDate), dateStr),
const SizedBox(height: 6),
infoRow(Icons.satellite_alt, context.translate(I18n.locationType), position.type),
const SizedBox(height: 6),
infoRow(
Icons.location_on_outlined,
context.translate(I18n.locationCoordinates),
'${position.latitude.toStringAsFixed(4)}, ${position.longitude.toStringAsFixed(4)}',
),
if (addressParts.isNotEmpty) ...[
const SizedBox(height: 6),
infoRow(Icons.place, context.translate(I18n.locationAddress), addressParts.join(', ')),
],
if (position.frequentPlaceName != null) ...[
const SizedBox(height: 6),
infoRow(Icons.home_rounded, context.translate(I18n.locationPlace), position.frequentPlaceName!,
iconColor: Colors.orange),
],
],
),
);
}
}

View File

@@ -0,0 +1,230 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:sf_localizations/sf_localizations.dart';
Widget infoRow(IconData icon, String label, String value,
{Color? iconColor}) {
return Row(
children: [
Icon(icon, size: 16, color: iconColor ?? Colors.grey.shade500),
const SizedBox(width: 6),
Text(
'$label: ',
style: TextStyle(fontSize: 12, color: Colors.grey.shade500),
),
Expanded(
child: Text(
value,
style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w500),
overflow: TextOverflow.ellipsis,
),
),
],
);
}
class MapItemInfoCard extends ConsumerWidget {
final IconData icon;
final Color iconColor;
final String title;
final VoidCallback onClose;
final VoidCallback onEdit;
final VoidCallback onDelete;
final Widget content;
const MapItemInfoCard({
super.key,
required this.icon,
required this.iconColor,
required this.title,
required this.onClose,
required this.onEdit,
required this.onDelete,
required this.content,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
final primaryColor =
ref.read(themePortProvider).getColorFor(ThemeCode.legacyPrimary);
return GestureDetector(
onTap: () {},
child: Container(
width: 280,
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.2),
blurRadius: 12,
offset: const Offset(0, 4),
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
padding: const EdgeInsets.all(6),
decoration: BoxDecoration(
color: iconColor.withValues(alpha: 0.15),
shape: BoxShape.circle,
),
child: Icon(icon, color: iconColor, size: 20),
),
const SizedBox(width: 10),
Expanded(
child: Text(
title,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
overflow: TextOverflow.ellipsis,
),
),
GestureDetector(
onTap: onClose,
child: Icon(Icons.close,
size: 20, color: Colors.grey.shade500),
),
],
),
const SizedBox(height: 12),
content,
const SizedBox(height: 14),
Row(
children: [
Expanded(
child: GestureDetector(
onTap: onEdit,
child: Container(
padding: const EdgeInsets.symmetric(vertical: 10),
decoration: BoxDecoration(
color: primaryColor,
borderRadius: BorderRadius.circular(10),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(Icons.edit, size: 16, color: Colors.white),
const SizedBox(width: 6),
Text(
context.translate(I18n.locationEdit),
style: const TextStyle(
color: Colors.white,
fontSize: 14,
fontWeight: FontWeight.w600,
),
),
],
),
),
),
),
const SizedBox(width: 10),
GestureDetector(
onTap: onDelete,
child: Container(
padding: const EdgeInsets.symmetric(
vertical: 10, horizontal: 14),
decoration: BoxDecoration(
color: Colors.grey.shade100,
borderRadius: BorderRadius.circular(10),
border: Border.all(color: Colors.grey.shade400),
),
child: Icon(
Icons.delete_outline,
size: 18,
color: Colors.grey.shade600,
),
),
),
],
),
],
),
),
);
}
}
class ReadOnlyInfoCard extends StatelessWidget {
final IconData icon;
final Color iconColor;
final String title;
final VoidCallback onClose;
final Widget content;
const ReadOnlyInfoCard({
super.key,
required this.icon,
required this.iconColor,
required this.title,
required this.onClose,
required this.content,
});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {},
child: Container(
width: 280,
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.2),
blurRadius: 12,
offset: const Offset(0, 4),
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
padding: const EdgeInsets.all(6),
decoration: BoxDecoration(
color: iconColor.withValues(alpha: 0.15),
shape: BoxShape.circle,
),
child: Icon(icon, color: iconColor, size: 20),
),
const SizedBox(width: 10),
Expanded(
child: Text(
title,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
overflow: TextOverflow.ellipsis,
),
),
GestureDetector(
onTap: onClose,
child: Icon(Icons.close, size: 20, color: Colors.grey.shade500),
),
],
),
const SizedBox(height: 12),
content,
],
),
),
);
}
}

View File

@@ -0,0 +1,25 @@
import 'package:flutter/material.dart';
class ModalOverlay extends StatelessWidget {
final VoidCallback onDismiss;
final Widget child;
const ModalOverlay({
super.key,
required this.onDismiss,
required this.child,
});
@override
Widget build(BuildContext context) {
return Positioned.fill(
child: GestureDetector(
onTap: onDismiss,
child: ColoredBox(
color: Colors.black.withValues(alpha: 0.3),
child: Center(child: child),
),
),
);
}
}

View File

@@ -0,0 +1,189 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:sf_localizations/sf_localizations.dart';
import 'package:utils/utils.dart';
import 'location_input_decoration.dart';
Future<void> showNameInputSheet(
BuildContext context, {
required WidgetRef ref,
required String title,
required String hintText,
bool showDescription = false,
String? initialName,
String? initialDescription,
String? submitLabel,
required Future<bool> Function(String name, String? description) onSubmit,
}) {
final primaryColor =
ref.read(themePortProvider).getColorFor(ThemeCode.legacyPrimary);
final resolvedSubmitLabel =
submitLabel ?? context.translate(I18n.locationCreate);
return showModalBottomSheet<void>(
context: context,
isScrollControlled: true,
backgroundColor: Colors.transparent,
builder: (_) => _NameInputSheetContent(
title: title,
hintText: hintText,
showDescription: showDescription,
initialName: initialName,
initialDescription: initialDescription,
submitLabel: resolvedSubmitLabel,
primaryColor: primaryColor,
onSubmit: onSubmit,
),
);
}
class _NameInputSheetContent extends StatefulWidget {
final String title;
final String hintText;
final bool showDescription;
final String? initialName;
final String? initialDescription;
final String submitLabel;
final Color primaryColor;
final Future<bool> Function(String name, String? description) onSubmit;
const _NameInputSheetContent({
required this.title,
required this.hintText,
required this.showDescription,
required this.initialName,
required this.initialDescription,
required this.submitLabel,
required this.primaryColor,
required this.onSubmit,
});
@override
State<_NameInputSheetContent> createState() =>
_NameInputSheetContentState();
}
class _NameInputSheetContentState extends State<_NameInputSheetContent> {
late final TextEditingController _nameController;
late final TextEditingController _descController;
@override
void initState() {
super.initState();
_nameController = TextEditingController(text: widget.initialName ?? '');
_descController =
TextEditingController(text: widget.initialDescription ?? '');
}
@override
void dispose() {
_nameController.dispose();
_descController.dispose();
super.dispose();
}
bool get _canSave => _nameController.text.trim().isNotEmpty;
@override
Widget build(BuildContext context) {
final bottomInset = MediaQuery.of(context).viewInsets.bottom;
return Padding(
padding: EdgeInsets.only(bottom: bottomInset),
child: Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
),
child: SafeArea(
top: false,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: SizeUtils.getByScreen(small: 22, big: 24),
vertical: SizeUtils.getByScreen(small: 16, big: 18),
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Center(
child: Container(
width: 40,
height: 4,
decoration: BoxDecoration(
color: Colors.grey.shade300,
borderRadius: BorderRadius.circular(2),
),
),
),
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),
),
),
),
],
),
const SizedBox(height: 12),
TextField(
controller: _nameController,
autofocus: true,
onChanged: (_) => setState(() {}),
decoration: locationInputDecoration(
hintText: widget.hintText,
primaryColor: widget.primaryColor,
),
),
if (widget.showDescription) ...[
const SizedBox(height: 12),
TextField(
controller: _descController,
decoration: locationInputDecoration(
hintText:
context.translate(I18n.locationHintDescription),
primaryColor: widget.primaryColor,
),
),
],
const SizedBox(height: 16),
],
),
),
),
),
);
}
}

View File

@@ -96,7 +96,7 @@ packages:
source: hosted
version: "3.0.3"
build_runner:
dependency: transitive
dependency: "direct dev"
description:
name: build_runner
sha256: b24597fceb695969d47025c958f3837f9f0122e237c6a22cb082a5ac66c3ca30
@@ -285,7 +285,7 @@ packages:
source: hosted
version: "0.1.6"
dio:
dependency: transitive
dependency: "direct main"
description:
name: dio
sha256: aff32c08f92787a557dd5c0145ac91536481831a01b4648136373cddb0e64f8c
@@ -370,7 +370,7 @@ packages:
source: hosted
version: "5.0.0"
flutter_map:
dependency: transitive
dependency: "direct main"
description:
name: flutter_map
sha256: "391e7dc95cc3f5190748210a69d4cfeb5d8f84dcdfa9c3235d0a9d7742ccb3f8"
@@ -386,7 +386,7 @@ packages:
source: hosted
version: "3.2.1"
flutter_svg:
dependency: transitive
dependency: "direct main"
description:
name: flutter_svg
sha256: "1ded017b39c8e15c8948ea855070a5ff8ff8b3d5e83f3446e02d6bb12add7ad9"
@@ -418,7 +418,7 @@ packages:
source: path
version: "0.0.1"
freezed:
dependency: transitive
dependency: "direct dev"
description:
name: freezed
sha256: "13065f10e135263a4f5a4391b79a8efc5fb8106f8dd555a9e49b750b45393d77"
@@ -426,7 +426,7 @@ packages:
source: hosted
version: "3.2.3"
freezed_annotation:
dependency: transitive
dependency: "direct main"
description:
name: freezed_annotation
sha256: "7294967ff0a6d98638e7acb774aac3af2550777accd8149c90af5b014e6d44d8"
@@ -529,7 +529,7 @@ packages:
source: hosted
version: "0.7.2"
json_annotation:
dependency: transitive
dependency: "direct main"
description:
name: json_annotation
sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1"
@@ -537,7 +537,7 @@ packages:
source: hosted
version: "4.9.0"
json_serializable:
dependency: transitive
dependency: "direct dev"
description:
name: json_serializable
sha256: c5b2ee75210a0f263c6c7b9eeea80553dbae96ea1bf57f02484e806a3ffdffa3
@@ -569,7 +569,7 @@ packages:
source: hosted
version: "1.3.0"
latlong2:
dependency: transitive
dependency: "direct main"
description:
name: latlong2
sha256: "98227922caf49e6056f91b6c56945ea1c7b166f28ffcd5fb8e72fc0b453cc8fe"
@@ -608,7 +608,7 @@ packages:
source: path
version: "0.0.1"
legacy_shared:
dependency: "direct overridden"
dependency: "direct main"
description:
path: "../../packages/legacy_shared"
relative: true
@@ -914,7 +914,7 @@ packages:
source: hosted
version: "2.5.0"
sf_infrastructure:
dependency: "direct overridden"
dependency: "direct main"
description:
path: "../../../../packages/sf_infrastructure"
relative: true
@@ -928,7 +928,7 @@ packages:
source: path
version: "0.0.1"
sf_shared:
dependency: "direct overridden"
dependency: "direct main"
description:
path: "../../../../packages/sf_shared"
relative: true
@@ -1251,7 +1251,7 @@ packages:
source: path
version: "0.0.1"
uuid:
dependency: transitive
dependency: "direct main"
description:
name: uuid
sha256: "1fef9e8e11e2991bb773070d4656b7bd5d850967a2456cfc83cf47925ba79489"

View File

@@ -16,15 +16,31 @@ dependencies:
path: ../../../../packages/design_system
sf_localizations:
path: ../../../../packages/sf_localizations
sf_infrastructure:
path: ../../../../packages/sf_infrastructure
legacy_shared:
path: ../../packages/legacy_shared
sf_shared:
path: ../../../../packages/sf_shared
utils:
path: ../../../../packages/utils
flutter_riverpod: ^3.0.3
go_router: ^17.0.0
freezed_annotation: ^3.1.0
json_annotation: ^4.9.0
dio: ^5.9.0
flutter_map: ^8.2.2
latlong2: ^0.9.1
flutter_svg: ^2.2.1
uuid: ^4.5.1
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^5.0.0
build_runner: ^2.7.1
freezed: ^3.2.3
json_serializable: ^6.11.2
flutter:
uses-material-design: true

View File

@@ -1,8 +1,10 @@
library legacy_shared;
export 'src/providers/map_style_provider.dart';
export 'src/providers/selected_device_provider.dart';
export 'src/widgets/layouts/page_layout.dart';
export 'src/components/section_button.dart';
export 'src/widgets/pulsing_location_marker.dart';
export 'src/widgets/week_day_chips.dart';
export 'src/components/menu_button.dart';
export 'src/data/models/device_response_model.dart';

View File

@@ -8,6 +8,8 @@ enum DeviceCommand {
factory,
@JsonValue('FIND_DEVICE')
findDevice,
@JsonValue('REQUEST_HEART_RATE')
requestHeartRate,
@JsonValue('RESTART')
restart,
@JsonValue('REWARDS')

View File

@@ -25,6 +25,7 @@ Map<String, dynamic> _$SendCommandRequestModelToJson(
const _$DeviceCommandEnumMap = {
DeviceCommand.factory: 'FACTORY',
DeviceCommand.findDevice: 'FIND_DEVICE',
DeviceCommand.requestHeartRate: 'REQUEST_HEART_RATE',
DeviceCommand.restart: 'RESTART',
DeviceCommand.rewards: 'REWARDS',
DeviceCommand.shutdown: 'SHUTDOWN',

View File

@@ -0,0 +1,44 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart';
const _mapStyleKey = 'location_map_style';
enum MapStyle {
standard('https://tile.openstreetmap.org/{z}/{x}/{y}.png'),
voyager('https://basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png'),
light('https://basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png'),
dark('https://basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png'),
satellite('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}');
const MapStyle(this.urlTemplate);
final String urlTemplate;
}
final mapStyleProvider =
NotifierProvider<MapStyleNotifier, MapStyle>(MapStyleNotifier.new);
class MapStyleNotifier extends Notifier<MapStyle> {
@override
MapStyle build() {
_load();
return MapStyle.standard;
}
Future<void> _load() async {
final prefs = await SharedPreferences.getInstance();
final savedName = prefs.getString(_mapStyleKey);
if (savedName == null) return;
final style =
MapStyle.values.where((s) => s.name == savedName).firstOrNull;
if (style != null && style != state) {
state = style;
}
}
Future<void> setStyle(MapStyle style) async {
state = style;
final prefs = await SharedPreferences.getInstance();
await prefs.setString(_mapStyleKey, style.name);
}
}

View File

@@ -0,0 +1,88 @@
import 'package:flutter/material.dart';
class PulsingLocationMarker extends StatefulWidget {
final Color? color;
const PulsingLocationMarker({super.key, this.color});
@override
State<PulsingLocationMarker> createState() => _PulsingLocationMarkerState();
}
class _PulsingLocationMarkerState extends State<PulsingLocationMarker>
with TickerProviderStateMixin {
late final AnimationController _controller1;
late final AnimationController _controller2;
@override
void initState() {
super.initState();
_controller1 = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 2000),
)..repeat();
_controller2 = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 2000),
);
Future.delayed(const Duration(milliseconds: 1000), () {
if (mounted) _controller2.repeat();
});
}
@override
void dispose() {
_controller1.dispose();
_controller2.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final c = widget.color ?? const Color(0xFF329E95);
return Stack(
alignment: Alignment.center,
children: [
_buildRipple(_controller1, c),
_buildRipple(_controller2, c),
Container(
width: 18,
height: 18,
decoration: BoxDecoration(
color: c,
shape: BoxShape.circle,
border: Border.all(color: Colors.white, width: 3),
boxShadow: [
BoxShadow(
color: c.withValues(alpha: 0.4),
blurRadius: 6,
spreadRadius: 1,
),
],
),
),
],
);
}
Widget _buildRipple(AnimationController controller, Color color) {
return AnimatedBuilder(
animation: controller,
builder: (context, child) {
final scale = 1.0 + controller.value * 2.5;
final opacity = (1.0 - controller.value).clamp(0.0, 0.5);
return Transform.scale(
scale: scale,
child: Container(
width: 18,
height: 18,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: color.withValues(alpha: opacity),
),
),
);
},
);
}
}

View File

@@ -892,7 +892,7 @@ packages:
source: path
version: "0.0.1"
shared_preferences:
dependency: transitive
dependency: "direct main"
description:
name: shared_preferences
sha256: "2939ae520c9024cb197fc20dee269cd8cdbf564c8b5746374ec6cacdc5169e64"

Some files were not shown because too many files have changed in this diff Show More