feat: sync device settings after updates and improve remote connection features

- Add DeviceSettingsSync extension on Ref to centralize device provider
    updates after settings changes (sound, volume, language, timezone,
    battery, disable functions, alerts, pedometer, heart rate freq,
    location freq, background image)
  - Add photo capture countdown with Lottie animation in remote camera
  - Replace Image.network with Image.memory for photo display
  - Fix commands datasource to handle text/html responses (post<dynamic>)
  - Add typed error/success events to RemoteConnectionViewModel
  - Add background image active indicator and backgroundImageId to device settings
  - Change photos endpoint from /devices/identificator/:id/photos/files to /photos/files
  - Remove dead deviceId param from getBackgroundImage chain
  - Relax PictureEntity required fields to @Default for API compatibility
  - Fix LocationViewModel rebuild crash (ref.watch → ref.read)
  - Use .select() in RemoteCameraScreen for optimized rebuilds
  - Increase health measure countdown to 60s
This commit is contained in:
2026-03-25 13:51:48 +01:00
parent a05c167f30
commit b7614a39f1
46 changed files with 489 additions and 232 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,9 +1,7 @@
import '../models/get_background_image_response_model.dart';
abstract class BackgroundImageRemoteDatasource {
Future<GetBackgroundImageResponseModel> getBackgroundImage({
required String deviceId,
});
Future<GetBackgroundImageResponseModel> getBackgroundImage();
Future<String> uploadImage({
required String path,

View File

@@ -6,17 +6,16 @@ import 'package:sf_infrastructure/configure_dependencies.dart';
import '../models/get_background_image_response_model.dart';
import 'background_image_remote_datasource.dart';
class BackgroundImageRemoteDatasourceImpl implements BackgroundImageRemoteDatasource {
class BackgroundImageRemoteDatasourceImpl
implements BackgroundImageRemoteDatasource {
BackgroundImageRemoteDatasourceImpl(this._repository);
final QuestiaRepository _repository;
@override
Future<GetBackgroundImageResponseModel> getBackgroundImage({required String deviceId}) async {
Future<GetBackgroundImageResponseModel> getBackgroundImage() async {
final response = await safeCall(
() => _repository.get<dynamic>(
'/devices/identificator/$deviceId/photos/files',
),
() => _repository.get<dynamic>('/photos/files'),
'Error getting background image',
);
@@ -39,10 +38,7 @@ class BackgroundImageRemoteDatasourceImpl implements BackgroundImageRemoteDataso
final dio = GetIt.I<Dio>();
dio.options.headers.remove('content-type');
try {
final response = await dio.post<dynamic>(
'/photos',
data: formData,
);
final response = await dio.post<dynamic>('/photos', data: formData);
final data = response.data;
if (data == null) {
@@ -74,4 +70,4 @@ class BackgroundImageRemoteDatasourceImpl implements BackgroundImageRemoteDataso
'Error setting background image',
);
}
}
}

View File

@@ -22,13 +22,13 @@ abstract class GetPicturesItemResponseModel
with _$GetPicturesItemResponseModel {
const factory GetPicturesItemResponseModel({
required String id,
required String deviceIdentificator,
@Default('') String deviceIdentificator,
String? imgType,
String? timestamp,
required String fileId,
@Default('') String fileId,
String? fileName,
String? contentType,
required int createdAt,
@Default(0) int createdAt,
Map<String, dynamic>? file,
}) = _GetPicturesItemResponseModel;

View File

@@ -486,17 +486,17 @@ return $default(_that.id,_that.deviceIdentificator,_that.imgType,_that.timestamp
@JsonSerializable()
class _GetPicturesItemResponseModel implements GetPicturesItemResponseModel {
const _GetPicturesItemResponseModel({required this.id, required this.deviceIdentificator, this.imgType, this.timestamp, required this.fileId, this.fileName, this.contentType, required this.createdAt, final Map<String, dynamic>? file}): _file = file;
const _GetPicturesItemResponseModel({required this.id, this.deviceIdentificator = '', this.imgType, this.timestamp, this.fileId = '', this.fileName, this.contentType, this.createdAt = 0, final Map<String, dynamic>? file}): _file = file;
factory _GetPicturesItemResponseModel.fromJson(Map<String, dynamic> json) => _$GetPicturesItemResponseModelFromJson(json);
@override final String id;
@override final String deviceIdentificator;
@override@JsonKey() final String deviceIdentificator;
@override final String? imgType;
@override final String? timestamp;
@override final String fileId;
@override@JsonKey() final String fileId;
@override final String? fileName;
@override final String? contentType;
@override final int createdAt;
@override@JsonKey() final int createdAt;
final Map<String, dynamic>? _file;
@override Map<String, dynamic>? get file {
final value = _file;

View File

@@ -24,13 +24,13 @@ _GetPicturesItemResponseModel _$GetPicturesItemResponseModelFromJson(
Map<String, dynamic> json,
) => _GetPicturesItemResponseModel(
id: json['id'] as String,
deviceIdentificator: json['deviceIdentificator'] as String,
deviceIdentificator: json['deviceIdentificator'] as String? ?? '',
imgType: json['imgType'] as String?,
timestamp: json['timestamp'] as String?,
fileId: json['fileId'] as String,
fileId: json['fileId'] as String? ?? '',
fileName: json['fileName'] as String?,
contentType: json['contentType'] as String?,
createdAt: (json['createdAt'] as num).toInt(),
createdAt: (json['createdAt'] as num?)?.toInt() ?? 0,
file: json['file'] as Map<String, dynamic>?,
);

View File

@@ -11,8 +11,8 @@ class BackgroundImageRepositoryImpl implements BackgroundImageRepository {
final BackgroundImageRemoteDatasource _remote;
@override
Future<List<PictureEntity>> getPhotos({required String deviceId}) async {
final model = await _remote.getBackgroundImage(deviceId: deviceId);
Future<List<PictureEntity>> getPhotos() async {
final model = await _remote.getBackgroundImage();
return model.toEntities();
}

View File

@@ -2,7 +2,7 @@
import 'package:device_management/src/features/remote_connection/domain/entities/picture_entity.dart';
abstract class BackgroundImageRepository {
Future<List<PictureEntity>> getPhotos({required String deviceId});
Future<List<PictureEntity>> getPhotos();
Future<String> uploadImage({required String path});
Future<void> setBackgroundImage({required String deviceId, required String photoId});
}

View File

@@ -255,6 +255,7 @@ class ActivityMeterViewModel extends Notifier<ActivityMeterViewState> {
updatedSettings: updatedSettings,
);
if (!ref.mounted) return false;
ref.syncDeviceSettings(device, updatedSettings);
return true;
} catch (e) {
if (!ref.mounted) return false;

View File

@@ -113,7 +113,7 @@ class BackgroundImageScreen extends ConsumerWidget {
)
: _PhotoGrid(
state: state,
vm: vm,
onPhotoTap: vm.setAsBackground,
primaryColor: primaryColor,
),
),
@@ -160,12 +160,12 @@ class _EmptyState extends StatelessWidget {
class _PhotoGrid extends StatelessWidget {
final BackgroundImageViewState state;
final BackgroundImageViewModel vm;
final ValueChanged<String> onPhotoTap;
final Color primaryColor;
const _PhotoGrid({
required this.state,
required this.vm,
required this.onPhotoTap,
required this.primaryColor,
});
@@ -192,28 +192,53 @@ class _PhotoGrid extends StatelessWidget {
itemCount: state.photos.length,
itemBuilder: (context, index) {
final photo = state.photos[index];
final isActive = state.currentBackgroundId == photo.id;
return GestureDetector(
onTap: () => vm.setAsBackground(photo.id),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Colors.grey.shade300,
),
),
clipBehavior: Clip.antiAlias,
child: photo.fileBytes != null
? Image.memory(
photo.fileBytes!,
fit: BoxFit.cover,
)
: Center(
child: Icon(
Icons.image_outlined,
size: 48,
color: Colors.grey.shade400,
onTap: () => onPhotoTap(photo.id),
child: Stack(
children: [
Positioned.fill(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: isActive ? primaryColor : Colors.grey.shade300,
width: isActive ? 3 : 1,
),
),
clipBehavior: Clip.antiAlias,
child: photo.fileBytes != null
? Image.memory(
photo.fileBytes!,
fit: BoxFit.cover,
)
: Center(
child: Icon(
Icons.image_outlined,
size: 48,
color: Colors.grey.shade400,
),
),
),
),
if (isActive)
Positioned(
top: 8,
right: 8,
child: Container(
padding: const EdgeInsets.all(4),
decoration: BoxDecoration(
color: primaryColor,
shape: BoxShape.circle,
),
child: const Icon(
Icons.check,
color: Colors.white,
size: 16,
),
),
),
],
),
);
},

View File

@@ -26,12 +26,14 @@ class BackgroundImageViewModel extends Notifier<BackgroundImageViewState> {
final device = ref.read(selectedDeviceProvider);
if (device == null) return;
final photos = await _repository.getPhotos(
deviceId: device.identificator,
);
final photos = await _repository.getPhotos();
if (!ref.mounted) return;
state = state.copyWith(photos: photos, isLoading: false);
state = state.copyWith(
photos: photos,
currentBackgroundId: device.settings.backgroundImageId,
isLoading: false,
);
} catch (e) {
if (!ref.mounted) return;
state = state.copyWith(
@@ -57,14 +59,29 @@ class BackgroundImageViewModel extends Notifier<BackgroundImageViewState> {
);
if (image == null) return;
final device = ref.read(selectedDeviceProvider);
if (device == null) return;
state = state.copyWith(isSaving: true, errorEvent: null, successEvent: null);
try {
await _repository.uploadImage(path: image.path);
final photoId = await _repository.uploadImage(path: image.path);
if (!ref.mounted) return;
await _repository.setBackgroundImage(
deviceId: device.id,
photoId: photoId,
);
if (!ref.mounted) return;
ref.syncDeviceSettings(
device,
device.settings.copyWith(backgroundImageId: photoId),
);
state = state.copyWith(
isSaving: false,
currentBackgroundId: photoId,
successEvent: BackgroundImageSuccessEvent.uploaded,
);
@@ -91,8 +108,14 @@ class BackgroundImageViewModel extends Notifier<BackgroundImageViewState> {
);
if (!ref.mounted) return;
ref.syncDeviceSettings(
device,
device.settings.copyWith(backgroundImageId: photoId),
);
state = state.copyWith(
isSaving: false,
currentBackgroundId: photoId,
successEvent: BackgroundImageSuccessEvent.backgroundSet,
);
} catch (e) {

View File

@@ -12,6 +12,7 @@ abstract class BackgroundImageViewState with _$BackgroundImageViewState {
@Default([]) List<PictureEntity> photos,
@Default(true) bool isLoading,
@Default(false) bool isSaving,
String? currentBackgroundId,
BackgroundImageSuccessEvent? successEvent,
BackgroundImageErrorEvent? errorEvent,
}) = _BackgroundImageViewState;

View File

@@ -14,7 +14,7 @@ T _$identity<T>(T value) => value;
/// @nodoc
mixin _$BackgroundImageViewState {
List<PictureEntity> get photos; bool get isLoading; bool get isSaving; BackgroundImageSuccessEvent? get successEvent; BackgroundImageErrorEvent? get errorEvent;
List<PictureEntity> get photos; bool get isLoading; bool get isSaving; String? get currentBackgroundId; BackgroundImageSuccessEvent? get successEvent; BackgroundImageErrorEvent? get errorEvent;
/// Create a copy of BackgroundImageViewState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -25,16 +25,16 @@ $BackgroundImageViewStateCopyWith<BackgroundImageViewState> get copyWith => _$Ba
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is BackgroundImageViewState&&const DeepCollectionEquality().equals(other.photos, photos)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isSaving, isSaving) || other.isSaving == isSaving)&&(identical(other.successEvent, successEvent) || other.successEvent == successEvent)&&(identical(other.errorEvent, errorEvent) || other.errorEvent == errorEvent));
return identical(this, other) || (other.runtimeType == runtimeType&&other is BackgroundImageViewState&&const DeepCollectionEquality().equals(other.photos, photos)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isSaving, isSaving) || other.isSaving == isSaving)&&(identical(other.currentBackgroundId, currentBackgroundId) || other.currentBackgroundId == currentBackgroundId)&&(identical(other.successEvent, successEvent) || other.successEvent == successEvent)&&(identical(other.errorEvent, errorEvent) || other.errorEvent == errorEvent));
}
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(photos),isLoading,isSaving,successEvent,errorEvent);
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(photos),isLoading,isSaving,currentBackgroundId,successEvent,errorEvent);
@override
String toString() {
return 'BackgroundImageViewState(photos: $photos, isLoading: $isLoading, isSaving: $isSaving, successEvent: $successEvent, errorEvent: $errorEvent)';
return 'BackgroundImageViewState(photos: $photos, isLoading: $isLoading, isSaving: $isSaving, currentBackgroundId: $currentBackgroundId, successEvent: $successEvent, errorEvent: $errorEvent)';
}
@@ -45,7 +45,7 @@ abstract mixin class $BackgroundImageViewStateCopyWith<$Res> {
factory $BackgroundImageViewStateCopyWith(BackgroundImageViewState value, $Res Function(BackgroundImageViewState) _then) = _$BackgroundImageViewStateCopyWithImpl;
@useResult
$Res call({
List<PictureEntity> photos, bool isLoading, bool isSaving, BackgroundImageSuccessEvent? successEvent, BackgroundImageErrorEvent? errorEvent
List<PictureEntity> photos, bool isLoading, bool isSaving, String? currentBackgroundId, BackgroundImageSuccessEvent? successEvent, BackgroundImageErrorEvent? errorEvent
});
@@ -62,12 +62,13 @@ class _$BackgroundImageViewStateCopyWithImpl<$Res>
/// Create a copy of BackgroundImageViewState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? photos = null,Object? isLoading = null,Object? isSaving = null,Object? successEvent = freezed,Object? errorEvent = freezed,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? photos = null,Object? isLoading = null,Object? isSaving = null,Object? currentBackgroundId = freezed,Object? successEvent = freezed,Object? errorEvent = freezed,}) {
return _then(_self.copyWith(
photos: null == photos ? _self.photos : photos // ignore: cast_nullable_to_non_nullable
as List<PictureEntity>,isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable
as bool,isSaving: null == isSaving ? _self.isSaving : isSaving // ignore: cast_nullable_to_non_nullable
as bool,successEvent: freezed == successEvent ? _self.successEvent : successEvent // ignore: cast_nullable_to_non_nullable
as bool,currentBackgroundId: freezed == currentBackgroundId ? _self.currentBackgroundId : currentBackgroundId // ignore: cast_nullable_to_non_nullable
as String?,successEvent: freezed == successEvent ? _self.successEvent : successEvent // ignore: cast_nullable_to_non_nullable
as BackgroundImageSuccessEvent?,errorEvent: freezed == errorEvent ? _self.errorEvent : errorEvent // ignore: cast_nullable_to_non_nullable
as BackgroundImageErrorEvent?,
));
@@ -154,10 +155,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( List<PictureEntity> photos, bool isLoading, bool isSaving, BackgroundImageSuccessEvent? successEvent, BackgroundImageErrorEvent? errorEvent)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( List<PictureEntity> photos, bool isLoading, bool isSaving, String? currentBackgroundId, BackgroundImageSuccessEvent? successEvent, BackgroundImageErrorEvent? errorEvent)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _BackgroundImageViewState() when $default != null:
return $default(_that.photos,_that.isLoading,_that.isSaving,_that.successEvent,_that.errorEvent);case _:
return $default(_that.photos,_that.isLoading,_that.isSaving,_that.currentBackgroundId,_that.successEvent,_that.errorEvent);case _:
return orElse();
}
@@ -175,10 +176,10 @@ return $default(_that.photos,_that.isLoading,_that.isSaving,_that.successEvent,_
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( List<PictureEntity> photos, bool isLoading, bool isSaving, BackgroundImageSuccessEvent? successEvent, BackgroundImageErrorEvent? errorEvent) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( List<PictureEntity> photos, bool isLoading, bool isSaving, String? currentBackgroundId, BackgroundImageSuccessEvent? successEvent, BackgroundImageErrorEvent? errorEvent) $default,) {final _that = this;
switch (_that) {
case _BackgroundImageViewState():
return $default(_that.photos,_that.isLoading,_that.isSaving,_that.successEvent,_that.errorEvent);case _:
return $default(_that.photos,_that.isLoading,_that.isSaving,_that.currentBackgroundId,_that.successEvent,_that.errorEvent);case _:
throw StateError('Unexpected subclass');
}
@@ -195,10 +196,10 @@ return $default(_that.photos,_that.isLoading,_that.isSaving,_that.successEvent,_
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( List<PictureEntity> photos, bool isLoading, bool isSaving, BackgroundImageSuccessEvent? successEvent, BackgroundImageErrorEvent? errorEvent)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( List<PictureEntity> photos, bool isLoading, bool isSaving, String? currentBackgroundId, BackgroundImageSuccessEvent? successEvent, BackgroundImageErrorEvent? errorEvent)? $default,) {final _that = this;
switch (_that) {
case _BackgroundImageViewState() when $default != null:
return $default(_that.photos,_that.isLoading,_that.isSaving,_that.successEvent,_that.errorEvent);case _:
return $default(_that.photos,_that.isLoading,_that.isSaving,_that.currentBackgroundId,_that.successEvent,_that.errorEvent);case _:
return null;
}
@@ -210,7 +211,7 @@ return $default(_that.photos,_that.isLoading,_that.isSaving,_that.successEvent,_
class _BackgroundImageViewState implements BackgroundImageViewState {
const _BackgroundImageViewState({final List<PictureEntity> photos = const [], this.isLoading = true, this.isSaving = false, this.successEvent, this.errorEvent}): _photos = photos;
const _BackgroundImageViewState({final List<PictureEntity> photos = const [], this.isLoading = true, this.isSaving = false, this.currentBackgroundId, this.successEvent, this.errorEvent}): _photos = photos;
final List<PictureEntity> _photos;
@@ -222,6 +223,7 @@ class _BackgroundImageViewState implements BackgroundImageViewState {
@override@JsonKey() final bool isLoading;
@override@JsonKey() final bool isSaving;
@override final String? currentBackgroundId;
@override final BackgroundImageSuccessEvent? successEvent;
@override final BackgroundImageErrorEvent? errorEvent;
@@ -235,16 +237,16 @@ _$BackgroundImageViewStateCopyWith<_BackgroundImageViewState> get copyWith => __
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _BackgroundImageViewState&&const DeepCollectionEquality().equals(other._photos, _photos)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isSaving, isSaving) || other.isSaving == isSaving)&&(identical(other.successEvent, successEvent) || other.successEvent == successEvent)&&(identical(other.errorEvent, errorEvent) || other.errorEvent == errorEvent));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _BackgroundImageViewState&&const DeepCollectionEquality().equals(other._photos, _photos)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isSaving, isSaving) || other.isSaving == isSaving)&&(identical(other.currentBackgroundId, currentBackgroundId) || other.currentBackgroundId == currentBackgroundId)&&(identical(other.successEvent, successEvent) || other.successEvent == successEvent)&&(identical(other.errorEvent, errorEvent) || other.errorEvent == errorEvent));
}
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_photos),isLoading,isSaving,successEvent,errorEvent);
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_photos),isLoading,isSaving,currentBackgroundId,successEvent,errorEvent);
@override
String toString() {
return 'BackgroundImageViewState(photos: $photos, isLoading: $isLoading, isSaving: $isSaving, successEvent: $successEvent, errorEvent: $errorEvent)';
return 'BackgroundImageViewState(photos: $photos, isLoading: $isLoading, isSaving: $isSaving, currentBackgroundId: $currentBackgroundId, successEvent: $successEvent, errorEvent: $errorEvent)';
}
@@ -255,7 +257,7 @@ abstract mixin class _$BackgroundImageViewStateCopyWith<$Res> implements $Backgr
factory _$BackgroundImageViewStateCopyWith(_BackgroundImageViewState value, $Res Function(_BackgroundImageViewState) _then) = __$BackgroundImageViewStateCopyWithImpl;
@override @useResult
$Res call({
List<PictureEntity> photos, bool isLoading, bool isSaving, BackgroundImageSuccessEvent? successEvent, BackgroundImageErrorEvent? errorEvent
List<PictureEntity> photos, bool isLoading, bool isSaving, String? currentBackgroundId, BackgroundImageSuccessEvent? successEvent, BackgroundImageErrorEvent? errorEvent
});
@@ -272,12 +274,13 @@ class __$BackgroundImageViewStateCopyWithImpl<$Res>
/// Create a copy of BackgroundImageViewState
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? photos = null,Object? isLoading = null,Object? isSaving = null,Object? successEvent = freezed,Object? errorEvent = freezed,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? photos = null,Object? isLoading = null,Object? isSaving = null,Object? currentBackgroundId = freezed,Object? successEvent = freezed,Object? errorEvent = freezed,}) {
return _then(_BackgroundImageViewState(
photos: null == photos ? _self._photos : photos // ignore: cast_nullable_to_non_nullable
as List<PictureEntity>,isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable
as bool,isSaving: null == isSaving ? _self.isSaving : isSaving // ignore: cast_nullable_to_non_nullable
as bool,successEvent: freezed == successEvent ? _self.successEvent : successEvent // ignore: cast_nullable_to_non_nullable
as bool,currentBackgroundId: freezed == currentBackgroundId ? _self.currentBackgroundId : currentBackgroundId // ignore: cast_nullable_to_non_nullable
as String?,successEvent: freezed == successEvent ? _self.successEvent : successEvent // ignore: cast_nullable_to_non_nullable
as BackgroundImageSuccessEvent?,errorEvent: freezed == errorEvent ? _self.errorEvent : errorEvent // ignore: cast_nullable_to_non_nullable
as BackgroundImageErrorEvent?,
));

View File

@@ -32,7 +32,7 @@ class HealthViewModel extends Notifier<HealthViewState> {
Timer? _measureTimer;
static const int _historyPageSize = 20;
static const int _measureDurationSeconds = 35;
static const int _measureDurationSeconds = 60;
@override
HealthViewState build() {
@@ -295,6 +295,7 @@ class HealthViewModel extends Notifier<HealthViewState> {
updatedSettings: updatedSettings,
);
if (!ref.mounted) return false;
ref.syncDeviceSettings(device, updatedSettings);
return true;
} catch (e) {
if (!ref.mounted) return false;

View File

@@ -8,13 +8,13 @@ part 'picture_entity.freezed.dart';
abstract class PictureEntity with _$PictureEntity {
const factory PictureEntity({
required String id,
required String deviceIdentificator,
@Default('') String deviceIdentificator,
String? imgType,
String? timestamp,
required String fileId,
@Default('') String fileId,
String? fileName,
String? contentType,
required int createdAt,
@Default(0) int createdAt,
Uint8List? fileBytes,
}) = _PictureEntity;
}

View File

@@ -214,17 +214,17 @@ return $default(_that.id,_that.deviceIdentificator,_that.imgType,_that.timestamp
class _PictureEntity implements PictureEntity {
const _PictureEntity({required this.id, required this.deviceIdentificator, this.imgType, this.timestamp, required this.fileId, this.fileName, this.contentType, required this.createdAt, this.fileBytes});
const _PictureEntity({required this.id, this.deviceIdentificator = '', this.imgType, this.timestamp, this.fileId = '', this.fileName, this.contentType, this.createdAt = 0, this.fileBytes});
@override final String id;
@override final String deviceIdentificator;
@override@JsonKey() final String deviceIdentificator;
@override final String? imgType;
@override final String? timestamp;
@override final String fileId;
@override@JsonKey() final String fileId;
@override final String? fileName;
@override final String? contentType;
@override final int createdAt;
@override@JsonKey() final int createdAt;
@override final Uint8List? fileBytes;
/// Create a copy of PictureEntity

View File

@@ -1,7 +1,9 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:lottie/lottie.dart';
import 'package:device_management/src/features/remote_connection/presentation/state/remote_connection_view_model.dart';
import 'package:device_management/src/features/remote_connection/presentation/state/remote_connection_view_state.dart';
import 'package:device_management/src/features/remote_connection/presentation/widgets/show_picture_dialog.dart';
import 'package:navigation/navigation.dart';
import 'package:sf_localizations/sf_localizations.dart';
@@ -17,10 +19,33 @@ class RemoteCameraScreen extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
ref.listen(
remoteConnectionViewModelProvider.select((s) => s.successMessage),
(_, successMessage) {
if (successMessage.isNotEmpty) {
showTopSnackbar(context, message: context.translate(successMessage), type: MessageType.success);
remoteConnectionViewModelProvider.select((s) => s.errorEvent),
(_, next) {
if (next != null) {
final message = switch (next) {
RemoteConnectionErrorEvent.takePicture =>
context.translate(I18n.errorTakePicture),
RemoteConnectionErrorEvent.fetchPhotos =>
context.translate(I18n.errorFetchPhotos),
RemoteConnectionErrorEvent.call =>
context.translate(I18n.errorCall),
RemoteConnectionErrorEvent.invalidPhone =>
context.translate(I18n.errorMessagePhoneIsInvalid),
};
showTopSnackbar(context, message: message, type: MessageType.error);
}
},
);
ref.listen(
remoteConnectionViewModelProvider.select((s) => s.successEvent),
(_, next) {
if (next != null) {
final message = switch (next) {
RemoteConnectionSuccessEvent.photoTaken =>
context.translate(I18n.photoTaken),
};
showTopSnackbar(context, message: message, type: MessageType.success);
ref.read(remoteConnectionViewModelProvider.notifier).clearSuccess();
}
},
@@ -28,20 +53,38 @@ class RemoteCameraScreen extends ConsumerWidget {
final theme = ref.watch(themePortProvider);
final isLoadingPictures = ref.watch(
remoteConnectionViewModelProvider.select((s)=>s.isLoadingPictures)
final isLoading = ref.watch(
remoteConnectionViewModelProvider.select((s) => s.isLoadingPictures),
);
final isTakingPicture = ref.watch(
remoteConnectionViewModelProvider.select((s)=>s.isTakingPicture)
final isTaking = ref.watch(
remoteConnectionViewModelProvider.select((s) => s.isTakingPicture),
);
final isWaiting = ref.watch(
remoteConnectionViewModelProvider.select((s) => s.isWaitingForPhoto),
);
final countdown = ref.watch(
remoteConnectionViewModelProvider.select((s) => s.photoCountdown),
);
Widget body;
if (isLoading || isTaking) {
body = const Center(child: CircularProgressIndicator());
} else if (isWaiting) {
body = _WaitingForPhotoOverlay(
remainingSeconds: countdown,
theme: theme,
);
} else {
body = const _GallerySection();
}
return LegacyPageLayout(
theme: theme,
title: context.translate(I18n.remoteCamera),
body: isLoadingPictures || isTakingPicture
? const Center(child: CircularProgressIndicator())
: const _GallerySection(),
footer: _TakePictureSection(),
body: body,
footer: isWaiting
? const SizedBox.shrink()
: const _TakePictureSection(),
);
}
}
@@ -87,12 +130,12 @@ class _GallerySection extends ConsumerWidget {
color: theme.getColorFor(ThemeCode.textTertiary)
))
),
child: Image.network(
pictures[index].fileId,
fit: BoxFit.cover,
errorBuilder: (_, __, ___) =>
const Icon(Icons.broken_image, color: Colors.grey),
)
child: pictures[index].fileBytes != null
? Image.memory(
pictures[index].fileBytes!,
fit: BoxFit.cover,
)
: const Icon(Icons.broken_image, color: Colors.grey),
)
)
),
@@ -124,5 +167,53 @@ class _TakePictureSection extends ConsumerWidget {
),
);
}
}
class _WaitingForPhotoOverlay extends StatelessWidget {
static const String _animationAsset =
'assets/shared/animations/shooting_photo.json';
final int remainingSeconds;
final ThemePort theme;
const _WaitingForPhotoOverlay({
required this.remainingSeconds,
required this.theme,
});
@override
Widget build(BuildContext context) {
final primaryColor = theme.getColorFor(ThemeCode.legacyPrimary);
return Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Lottie.asset(
_animationAsset,
width: 200,
height: 200,
),
const SizedBox(height: 24),
Text(
context.translate(I18n.takingPhoto),
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
color: primaryColor,
),
),
const SizedBox(height: 12),
Text(
'${remainingSeconds}s',
style: TextStyle(
fontSize: 32,
fontWeight: FontWeight.bold,
color: primaryColor,
),
),
],
),
);
}
}

View File

@@ -1,10 +1,11 @@
import 'dart:async';
import 'package:device_management/src/core/providers/pictures_repository_provider.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:device_management/src/features/remote_connection/domain/entities/picture_entity.dart';
import 'package:device_management/src/features/remote_connection/presentation/state/remote_connection_view_state.dart';
import 'package:legacy_shared/legacy_shared.dart';
import 'package:sf_localizations/sf_localizations.dart';
import '../../../../core/domain/repositories/pictures_repository.dart';
@@ -18,8 +19,10 @@ class RemoteConnectionViewModel extends Notifier<RemoteConnectionViewState> {
late final TextEditingController phoneController;
late final CommandsRepository _commandsRepository;
late final PicturesRepository _picturesRepository;
Timer? _photoTimer;
static final RegExp _phoneRegex = RegExp(r'^\+?\d{6,15}$');
static const int _photoWaitSeconds = 5;
@override
RemoteConnectionViewState build() {
@@ -60,12 +63,12 @@ class RemoteConnectionViewModel extends Notifier<RemoteConnectionViewState> {
final text = phoneController.text;
if (text == state.phone) return;
state = state.copyWith(phone: text, errorMessage: '');
state = state.copyWith(phone: text, errorEvent: null);
}
void updateDialCode(String value) {
if (value == state.dialCode) return;
state = state.copyWith(dialCode: value, errorMessage: '');
state = state.copyWith(dialCode: value, errorEvent: null);
}
void prevPicture() {
@@ -95,18 +98,17 @@ class RemoteConnectionViewModel extends Notifier<RemoteConnectionViewState> {
}
void clearSuccess() {
state = state.copyWith(
successMessage: '',
);
state = state.copyWith(successEvent: null);
}
Future<void> takePicture() async {
try {
state = state.copyWith(
isTakingPicture: true,
successMessage: '',
successEvent: null,
errorEvent: null,
);
final request = SendCommandRequestModel(
device: state.deviceId,
command: DeviceCommand.requestPhoto,
@@ -115,21 +117,59 @@ class RemoteConnectionViewModel extends Notifier<RemoteConnectionViewState> {
await _commandsRepository.send(request: request);
if (!ref.mounted) return;
state = state.copyWith(
isTakingPicture: false,
isWaitingForPhoto: true,
photoCountdown: _photoWaitSeconds,
);
_startPhotoCountdown();
} catch (e) {
if (!ref.mounted) return;
state = state.copyWith(
isTakingPicture: false,
errorEvent: RemoteConnectionErrorEvent.takePicture,
);
}
}
void _startPhotoCountdown() {
_photoTimer?.cancel();
_photoTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
if (!ref.mounted) {
timer.cancel();
return;
}
final remaining = state.photoCountdown - 1;
if (remaining <= 0) {
timer.cancel();
_photoTimer = null;
_fetchPhotosAfterCapture();
} else {
state = state.copyWith(photoCountdown: remaining);
}
});
}
Future<void> _fetchPhotosAfterCapture() async {
try {
final pictures = await _picturesRepository.getPictures(
deviceId: state.deviceId,
);
if (!ref.mounted) return;
state = state.copyWith(
isTakingPicture: false,
isWaitingForPhoto: false,
photoCountdown: 0,
pictures: pictures,
successMessage: I18n.photoTaken,
successEvent: RemoteConnectionSuccessEvent.photoTaken,
);
} catch (e) {
if (!ref.mounted) return;
state = state.copyWith(
isTakingPicture: false,
errorMessage: e.toString(),
isWaitingForPhoto: false,
photoCountdown: 0,
errorEvent: RemoteConnectionErrorEvent.fetchPhotos,
);
}
}
@@ -137,12 +177,8 @@ class RemoteConnectionViewModel extends Notifier<RemoteConnectionViewState> {
Future<void> call() async {
final phone = phoneController.text;
final dialCode = state.dialCode;
if (phone.isEmpty){
state = state.copyWith(errorMessage: I18n.errorMessagePhoneIsInvalid);
return;
}
if (!_phoneRegex.hasMatch(phone)) {
state = state.copyWith(errorMessage: I18n.errorMessagePhoneIsInvalid);
if (phone.isEmpty || !_phoneRegex.hasMatch(phone)) {
state = state.copyWith(errorEvent: RemoteConnectionErrorEvent.invalidPhone);
return;
}
@@ -163,7 +199,7 @@ class RemoteConnectionViewModel extends Notifier<RemoteConnectionViewState> {
if (!ref.mounted) return;
state = state.copyWith(
isCalling: false,
errorMessage: e.toString(),
errorEvent: RemoteConnectionErrorEvent.call,
);
}
}

View File

@@ -3,6 +3,9 @@ import 'package:device_management/src/features/remote_connection/domain/entities
part 'remote_connection_view_state.freezed.dart';
enum RemoteConnectionErrorEvent { takePicture, fetchPhotos, call, invalidPhone }
enum RemoteConnectionSuccessEvent { photoTaken }
@freezed
abstract class RemoteConnectionViewState with _$RemoteConnectionViewState {
const factory RemoteConnectionViewState({
@@ -13,8 +16,10 @@ abstract class RemoteConnectionViewState with _$RemoteConnectionViewState {
@Default(0) int pictureIndex,
@Default(true) bool isLoadingPictures,
@Default(false) bool isTakingPicture,
@Default(false) bool isWaitingForPhoto,
@Default(0) int photoCountdown,
@Default(false) bool isCalling,
@Default('') String errorMessage,
@Default('') String successMessage
RemoteConnectionErrorEvent? errorEvent,
RemoteConnectionSuccessEvent? successEvent,
}) = _RemoteConnectionViewState;
}

View File

@@ -14,7 +14,7 @@ T _$identity<T>(T value) => value;
/// @nodoc
mixin _$RemoteConnectionViewState {
String get deviceId; String get dialCode; String get phone; List<PictureEntity> get pictures; int get pictureIndex; bool get isLoadingPictures; bool get isTakingPicture; bool get isCalling; String get errorMessage; String get successMessage;
String get deviceId; String get dialCode; String get phone; List<PictureEntity> get pictures; int get pictureIndex; bool get isLoadingPictures; bool get isTakingPicture; bool get isWaitingForPhoto; int get photoCountdown; bool get isCalling; RemoteConnectionErrorEvent? get errorEvent; RemoteConnectionSuccessEvent? get successEvent;
/// Create a copy of RemoteConnectionViewState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -25,16 +25,16 @@ $RemoteConnectionViewStateCopyWith<RemoteConnectionViewState> get copyWith => _$
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is RemoteConnectionViewState&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId)&&(identical(other.dialCode, dialCode) || other.dialCode == dialCode)&&(identical(other.phone, phone) || other.phone == phone)&&const DeepCollectionEquality().equals(other.pictures, pictures)&&(identical(other.pictureIndex, pictureIndex) || other.pictureIndex == pictureIndex)&&(identical(other.isLoadingPictures, isLoadingPictures) || other.isLoadingPictures == isLoadingPictures)&&(identical(other.isTakingPicture, isTakingPicture) || other.isTakingPicture == isTakingPicture)&&(identical(other.isCalling, isCalling) || other.isCalling == isCalling)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)&&(identical(other.successMessage, successMessage) || other.successMessage == successMessage));
return identical(this, other) || (other.runtimeType == runtimeType&&other is RemoteConnectionViewState&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId)&&(identical(other.dialCode, dialCode) || other.dialCode == dialCode)&&(identical(other.phone, phone) || other.phone == phone)&&const DeepCollectionEquality().equals(other.pictures, pictures)&&(identical(other.pictureIndex, pictureIndex) || other.pictureIndex == pictureIndex)&&(identical(other.isLoadingPictures, isLoadingPictures) || other.isLoadingPictures == isLoadingPictures)&&(identical(other.isTakingPicture, isTakingPicture) || other.isTakingPicture == isTakingPicture)&&(identical(other.isWaitingForPhoto, isWaitingForPhoto) || other.isWaitingForPhoto == isWaitingForPhoto)&&(identical(other.photoCountdown, photoCountdown) || other.photoCountdown == photoCountdown)&&(identical(other.isCalling, isCalling) || other.isCalling == isCalling)&&(identical(other.errorEvent, errorEvent) || other.errorEvent == errorEvent)&&(identical(other.successEvent, successEvent) || other.successEvent == successEvent));
}
@override
int get hashCode => Object.hash(runtimeType,deviceId,dialCode,phone,const DeepCollectionEquality().hash(pictures),pictureIndex,isLoadingPictures,isTakingPicture,isCalling,errorMessage,successMessage);
int get hashCode => Object.hash(runtimeType,deviceId,dialCode,phone,const DeepCollectionEquality().hash(pictures),pictureIndex,isLoadingPictures,isTakingPicture,isWaitingForPhoto,photoCountdown,isCalling,errorEvent,successEvent);
@override
String toString() {
return 'RemoteConnectionViewState(deviceId: $deviceId, dialCode: $dialCode, phone: $phone, pictures: $pictures, pictureIndex: $pictureIndex, isLoadingPictures: $isLoadingPictures, isTakingPicture: $isTakingPicture, isCalling: $isCalling, errorMessage: $errorMessage, successMessage: $successMessage)';
return 'RemoteConnectionViewState(deviceId: $deviceId, dialCode: $dialCode, phone: $phone, pictures: $pictures, pictureIndex: $pictureIndex, isLoadingPictures: $isLoadingPictures, isTakingPicture: $isTakingPicture, isWaitingForPhoto: $isWaitingForPhoto, photoCountdown: $photoCountdown, isCalling: $isCalling, errorEvent: $errorEvent, successEvent: $successEvent)';
}
@@ -45,7 +45,7 @@ abstract mixin class $RemoteConnectionViewStateCopyWith<$Res> {
factory $RemoteConnectionViewStateCopyWith(RemoteConnectionViewState value, $Res Function(RemoteConnectionViewState) _then) = _$RemoteConnectionViewStateCopyWithImpl;
@useResult
$Res call({
String deviceId, String dialCode, String phone, List<PictureEntity> pictures, int pictureIndex, bool isLoadingPictures, bool isTakingPicture, bool isCalling, String errorMessage, String successMessage
String deviceId, String dialCode, String phone, List<PictureEntity> pictures, int pictureIndex, bool isLoadingPictures, bool isTakingPicture, bool isWaitingForPhoto, int photoCountdown, bool isCalling, RemoteConnectionErrorEvent? errorEvent, RemoteConnectionSuccessEvent? successEvent
});
@@ -62,7 +62,7 @@ class _$RemoteConnectionViewStateCopyWithImpl<$Res>
/// Create a copy of RemoteConnectionViewState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? deviceId = null,Object? dialCode = null,Object? phone = null,Object? pictures = null,Object? pictureIndex = null,Object? isLoadingPictures = null,Object? isTakingPicture = null,Object? isCalling = null,Object? errorMessage = null,Object? successMessage = null,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? deviceId = null,Object? dialCode = null,Object? phone = null,Object? pictures = null,Object? pictureIndex = null,Object? isLoadingPictures = null,Object? isTakingPicture = null,Object? isWaitingForPhoto = null,Object? photoCountdown = null,Object? isCalling = null,Object? errorEvent = freezed,Object? successEvent = freezed,}) {
return _then(_self.copyWith(
deviceId: null == deviceId ? _self.deviceId : deviceId // ignore: cast_nullable_to_non_nullable
as String,dialCode: null == dialCode ? _self.dialCode : dialCode // ignore: cast_nullable_to_non_nullable
@@ -71,10 +71,12 @@ as String,pictures: null == pictures ? _self.pictures : pictures // ignore: cast
as List<PictureEntity>,pictureIndex: null == pictureIndex ? _self.pictureIndex : pictureIndex // ignore: cast_nullable_to_non_nullable
as int,isLoadingPictures: null == isLoadingPictures ? _self.isLoadingPictures : isLoadingPictures // ignore: cast_nullable_to_non_nullable
as bool,isTakingPicture: null == isTakingPicture ? _self.isTakingPicture : isTakingPicture // ignore: cast_nullable_to_non_nullable
as bool,isCalling: null == isCalling ? _self.isCalling : isCalling // ignore: cast_nullable_to_non_nullable
as bool,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
as String,successMessage: null == successMessage ? _self.successMessage : successMessage // ignore: cast_nullable_to_non_nullable
as String,
as bool,isWaitingForPhoto: null == isWaitingForPhoto ? _self.isWaitingForPhoto : isWaitingForPhoto // ignore: cast_nullable_to_non_nullable
as bool,photoCountdown: null == photoCountdown ? _self.photoCountdown : photoCountdown // ignore: cast_nullable_to_non_nullable
as int,isCalling: null == isCalling ? _self.isCalling : isCalling // ignore: cast_nullable_to_non_nullable
as bool,errorEvent: freezed == errorEvent ? _self.errorEvent : errorEvent // ignore: cast_nullable_to_non_nullable
as RemoteConnectionErrorEvent?,successEvent: freezed == successEvent ? _self.successEvent : successEvent // ignore: cast_nullable_to_non_nullable
as RemoteConnectionSuccessEvent?,
));
}
@@ -159,10 +161,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String deviceId, String dialCode, String phone, List<PictureEntity> pictures, int pictureIndex, bool isLoadingPictures, bool isTakingPicture, bool isCalling, String errorMessage, String successMessage)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String deviceId, String dialCode, String phone, List<PictureEntity> pictures, int pictureIndex, bool isLoadingPictures, bool isTakingPicture, bool isWaitingForPhoto, int photoCountdown, bool isCalling, RemoteConnectionErrorEvent? errorEvent, RemoteConnectionSuccessEvent? successEvent)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _RemoteConnectionViewState() when $default != null:
return $default(_that.deviceId,_that.dialCode,_that.phone,_that.pictures,_that.pictureIndex,_that.isLoadingPictures,_that.isTakingPicture,_that.isCalling,_that.errorMessage,_that.successMessage);case _:
return $default(_that.deviceId,_that.dialCode,_that.phone,_that.pictures,_that.pictureIndex,_that.isLoadingPictures,_that.isTakingPicture,_that.isWaitingForPhoto,_that.photoCountdown,_that.isCalling,_that.errorEvent,_that.successEvent);case _:
return orElse();
}
@@ -180,10 +182,10 @@ return $default(_that.deviceId,_that.dialCode,_that.phone,_that.pictures,_that.p
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String deviceId, String dialCode, String phone, List<PictureEntity> pictures, int pictureIndex, bool isLoadingPictures, bool isTakingPicture, bool isCalling, String errorMessage, String successMessage) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String deviceId, String dialCode, String phone, List<PictureEntity> pictures, int pictureIndex, bool isLoadingPictures, bool isTakingPicture, bool isWaitingForPhoto, int photoCountdown, bool isCalling, RemoteConnectionErrorEvent? errorEvent, RemoteConnectionSuccessEvent? successEvent) $default,) {final _that = this;
switch (_that) {
case _RemoteConnectionViewState():
return $default(_that.deviceId,_that.dialCode,_that.phone,_that.pictures,_that.pictureIndex,_that.isLoadingPictures,_that.isTakingPicture,_that.isCalling,_that.errorMessage,_that.successMessage);case _:
return $default(_that.deviceId,_that.dialCode,_that.phone,_that.pictures,_that.pictureIndex,_that.isLoadingPictures,_that.isTakingPicture,_that.isWaitingForPhoto,_that.photoCountdown,_that.isCalling,_that.errorEvent,_that.successEvent);case _:
throw StateError('Unexpected subclass');
}
@@ -200,10 +202,10 @@ return $default(_that.deviceId,_that.dialCode,_that.phone,_that.pictures,_that.p
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String deviceId, String dialCode, String phone, List<PictureEntity> pictures, int pictureIndex, bool isLoadingPictures, bool isTakingPicture, bool isCalling, String errorMessage, String successMessage)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String deviceId, String dialCode, String phone, List<PictureEntity> pictures, int pictureIndex, bool isLoadingPictures, bool isTakingPicture, bool isWaitingForPhoto, int photoCountdown, bool isCalling, RemoteConnectionErrorEvent? errorEvent, RemoteConnectionSuccessEvent? successEvent)? $default,) {final _that = this;
switch (_that) {
case _RemoteConnectionViewState() when $default != null:
return $default(_that.deviceId,_that.dialCode,_that.phone,_that.pictures,_that.pictureIndex,_that.isLoadingPictures,_that.isTakingPicture,_that.isCalling,_that.errorMessage,_that.successMessage);case _:
return $default(_that.deviceId,_that.dialCode,_that.phone,_that.pictures,_that.pictureIndex,_that.isLoadingPictures,_that.isTakingPicture,_that.isWaitingForPhoto,_that.photoCountdown,_that.isCalling,_that.errorEvent,_that.successEvent);case _:
return null;
}
@@ -215,7 +217,7 @@ return $default(_that.deviceId,_that.dialCode,_that.phone,_that.pictures,_that.p
class _RemoteConnectionViewState implements RemoteConnectionViewState {
const _RemoteConnectionViewState({this.deviceId = '', this.dialCode = '+34', this.phone = '', final List<PictureEntity> pictures = const [], this.pictureIndex = 0, this.isLoadingPictures = true, this.isTakingPicture = false, this.isCalling = false, this.errorMessage = '', this.successMessage = ''}): _pictures = pictures;
const _RemoteConnectionViewState({this.deviceId = '', this.dialCode = '+34', this.phone = '', final List<PictureEntity> pictures = const [], this.pictureIndex = 0, this.isLoadingPictures = true, this.isTakingPicture = false, this.isWaitingForPhoto = false, this.photoCountdown = 0, this.isCalling = false, this.errorEvent, this.successEvent}): _pictures = pictures;
@override@JsonKey() final String deviceId;
@@ -231,9 +233,11 @@ class _RemoteConnectionViewState implements RemoteConnectionViewState {
@override@JsonKey() final int pictureIndex;
@override@JsonKey() final bool isLoadingPictures;
@override@JsonKey() final bool isTakingPicture;
@override@JsonKey() final bool isWaitingForPhoto;
@override@JsonKey() final int photoCountdown;
@override@JsonKey() final bool isCalling;
@override@JsonKey() final String errorMessage;
@override@JsonKey() final String successMessage;
@override final RemoteConnectionErrorEvent? errorEvent;
@override final RemoteConnectionSuccessEvent? successEvent;
/// Create a copy of RemoteConnectionViewState
/// with the given fields replaced by the non-null parameter values.
@@ -245,16 +249,16 @@ _$RemoteConnectionViewStateCopyWith<_RemoteConnectionViewState> get copyWith =>
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _RemoteConnectionViewState&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId)&&(identical(other.dialCode, dialCode) || other.dialCode == dialCode)&&(identical(other.phone, phone) || other.phone == phone)&&const DeepCollectionEquality().equals(other._pictures, _pictures)&&(identical(other.pictureIndex, pictureIndex) || other.pictureIndex == pictureIndex)&&(identical(other.isLoadingPictures, isLoadingPictures) || other.isLoadingPictures == isLoadingPictures)&&(identical(other.isTakingPicture, isTakingPicture) || other.isTakingPicture == isTakingPicture)&&(identical(other.isCalling, isCalling) || other.isCalling == isCalling)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)&&(identical(other.successMessage, successMessage) || other.successMessage == successMessage));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _RemoteConnectionViewState&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId)&&(identical(other.dialCode, dialCode) || other.dialCode == dialCode)&&(identical(other.phone, phone) || other.phone == phone)&&const DeepCollectionEquality().equals(other._pictures, _pictures)&&(identical(other.pictureIndex, pictureIndex) || other.pictureIndex == pictureIndex)&&(identical(other.isLoadingPictures, isLoadingPictures) || other.isLoadingPictures == isLoadingPictures)&&(identical(other.isTakingPicture, isTakingPicture) || other.isTakingPicture == isTakingPicture)&&(identical(other.isWaitingForPhoto, isWaitingForPhoto) || other.isWaitingForPhoto == isWaitingForPhoto)&&(identical(other.photoCountdown, photoCountdown) || other.photoCountdown == photoCountdown)&&(identical(other.isCalling, isCalling) || other.isCalling == isCalling)&&(identical(other.errorEvent, errorEvent) || other.errorEvent == errorEvent)&&(identical(other.successEvent, successEvent) || other.successEvent == successEvent));
}
@override
int get hashCode => Object.hash(runtimeType,deviceId,dialCode,phone,const DeepCollectionEquality().hash(_pictures),pictureIndex,isLoadingPictures,isTakingPicture,isCalling,errorMessage,successMessage);
int get hashCode => Object.hash(runtimeType,deviceId,dialCode,phone,const DeepCollectionEquality().hash(_pictures),pictureIndex,isLoadingPictures,isTakingPicture,isWaitingForPhoto,photoCountdown,isCalling,errorEvent,successEvent);
@override
String toString() {
return 'RemoteConnectionViewState(deviceId: $deviceId, dialCode: $dialCode, phone: $phone, pictures: $pictures, pictureIndex: $pictureIndex, isLoadingPictures: $isLoadingPictures, isTakingPicture: $isTakingPicture, isCalling: $isCalling, errorMessage: $errorMessage, successMessage: $successMessage)';
return 'RemoteConnectionViewState(deviceId: $deviceId, dialCode: $dialCode, phone: $phone, pictures: $pictures, pictureIndex: $pictureIndex, isLoadingPictures: $isLoadingPictures, isTakingPicture: $isTakingPicture, isWaitingForPhoto: $isWaitingForPhoto, photoCountdown: $photoCountdown, isCalling: $isCalling, errorEvent: $errorEvent, successEvent: $successEvent)';
}
@@ -265,7 +269,7 @@ abstract mixin class _$RemoteConnectionViewStateCopyWith<$Res> implements $Remot
factory _$RemoteConnectionViewStateCopyWith(_RemoteConnectionViewState value, $Res Function(_RemoteConnectionViewState) _then) = __$RemoteConnectionViewStateCopyWithImpl;
@override @useResult
$Res call({
String deviceId, String dialCode, String phone, List<PictureEntity> pictures, int pictureIndex, bool isLoadingPictures, bool isTakingPicture, bool isCalling, String errorMessage, String successMessage
String deviceId, String dialCode, String phone, List<PictureEntity> pictures, int pictureIndex, bool isLoadingPictures, bool isTakingPicture, bool isWaitingForPhoto, int photoCountdown, bool isCalling, RemoteConnectionErrorEvent? errorEvent, RemoteConnectionSuccessEvent? successEvent
});
@@ -282,7 +286,7 @@ class __$RemoteConnectionViewStateCopyWithImpl<$Res>
/// Create a copy of RemoteConnectionViewState
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? deviceId = null,Object? dialCode = null,Object? phone = null,Object? pictures = null,Object? pictureIndex = null,Object? isLoadingPictures = null,Object? isTakingPicture = null,Object? isCalling = null,Object? errorMessage = null,Object? successMessage = null,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? deviceId = null,Object? dialCode = null,Object? phone = null,Object? pictures = null,Object? pictureIndex = null,Object? isLoadingPictures = null,Object? isTakingPicture = null,Object? isWaitingForPhoto = null,Object? photoCountdown = null,Object? isCalling = null,Object? errorEvent = freezed,Object? successEvent = freezed,}) {
return _then(_RemoteConnectionViewState(
deviceId: null == deviceId ? _self.deviceId : deviceId // ignore: cast_nullable_to_non_nullable
as String,dialCode: null == dialCode ? _self.dialCode : dialCode // ignore: cast_nullable_to_non_nullable
@@ -291,10 +295,12 @@ as String,pictures: null == pictures ? _self._pictures : pictures // ignore: cas
as List<PictureEntity>,pictureIndex: null == pictureIndex ? _self.pictureIndex : pictureIndex // ignore: cast_nullable_to_non_nullable
as int,isLoadingPictures: null == isLoadingPictures ? _self.isLoadingPictures : isLoadingPictures // ignore: cast_nullable_to_non_nullable
as bool,isTakingPicture: null == isTakingPicture ? _self.isTakingPicture : isTakingPicture // ignore: cast_nullable_to_non_nullable
as bool,isCalling: null == isCalling ? _self.isCalling : isCalling // ignore: cast_nullable_to_non_nullable
as bool,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
as String,successMessage: null == successMessage ? _self.successMessage : successMessage // ignore: cast_nullable_to_non_nullable
as String,
as bool,isWaitingForPhoto: null == isWaitingForPhoto ? _self.isWaitingForPhoto : isWaitingForPhoto // ignore: cast_nullable_to_non_nullable
as bool,photoCountdown: null == photoCountdown ? _self.photoCountdown : photoCountdown // ignore: cast_nullable_to_non_nullable
as int,isCalling: null == isCalling ? _self.isCalling : isCalling // ignore: cast_nullable_to_non_nullable
as bool,errorEvent: freezed == errorEvent ? _self.errorEvent : errorEvent // ignore: cast_nullable_to_non_nullable
as RemoteConnectionErrorEvent?,successEvent: freezed == successEvent ? _self.successEvent : successEvent // ignore: cast_nullable_to_non_nullable
as RemoteConnectionSuccessEvent?,
));
}

View File

@@ -45,7 +45,7 @@ class ShowPictureDialog extends ConsumerWidget {
child: Column(
children: [
Expanded(
child: _PictureSection(fileId: picture.fileId),
child: _PictureSection(picture: picture),
),
_MetadataSection(picture: picture),
_ControlsSection(
@@ -59,24 +59,22 @@ class ShowPictureDialog extends ConsumerWidget {
}
class _PictureSection extends StatelessWidget {
final String fileId;
final PictureEntity picture;
const _PictureSection({required this.fileId});
const _PictureSection({required this.picture});
@override
Widget build(BuildContext context) {
return Center(
child: Image.network(
fileId,
fit: BoxFit.contain,
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) return child;
return const Center(child: CircularProgressIndicator());
},
errorBuilder: (context, error, stackTrace) {
return const Icon(Icons.broken_image, size: 64, color: Colors.grey);
},
),
if (picture.fileBytes != null) {
return Center(
child: Image.memory(
picture.fileBytes!,
fit: BoxFit.contain,
),
);
}
return const Center(
child: Icon(Icons.broken_image, size: 64, color: Colors.grey),
);
}
}

View File

@@ -2,6 +2,7 @@ import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:device_management/src/features/remote_connection/presentation/state/remote_connection_view_model.dart';
import 'package:device_management/src/features/remote_connection/presentation/state/remote_connection_view_state.dart';
import 'package:sf_localizations/sf_localizations.dart';
import 'package:utils/utils.dart';
@@ -13,26 +14,39 @@ class SpyCallDialog extends ConsumerWidget {
final theme = ref.watch(themePortProvider);
final vm = ref.read(remoteConnectionViewModelProvider.notifier);
ref.listen(remoteConnectionViewModelProvider.select((s) => s.errorMessage),
(_, msg) {
if (msg.isNotEmpty) {
showTopSnackbar(context,
message: context.translate(msg), type: MessageType.error);
}
});
ref.listen(remoteConnectionViewModelProvider.select((s) => s.isCalling),
(prev, isCalling) {
if (prev == true && !isCalling) {
final error = ref.read(remoteConnectionViewModelProvider).errorMessage;
if (error.isEmpty && context.mounted) {
Navigator.pop(context);
showTopSnackbar(context,
message: context.translate(I18n.remoteListening),
type: MessageType.success);
ref.listen(
remoteConnectionViewModelProvider.select((s) => s.errorEvent),
(_, next) {
if (next != null) {
final message = switch (next) {
RemoteConnectionErrorEvent.invalidPhone =>
context.translate(I18n.errorMessagePhoneIsInvalid),
RemoteConnectionErrorEvent.call =>
context.translate(I18n.errorCall),
RemoteConnectionErrorEvent.takePicture =>
context.translate(I18n.errorTakePicture),
RemoteConnectionErrorEvent.fetchPhotos =>
context.translate(I18n.errorFetchPhotos),
};
showTopSnackbar(context, message: message, type: MessageType.error);
}
}
});
},
);
ref.listen(
remoteConnectionViewModelProvider.select((s) => s.isCalling),
(prev, isCalling) {
if (prev == true && !isCalling) {
final error = ref.read(remoteConnectionViewModelProvider).errorEvent;
if (error == null && context.mounted) {
Navigator.pop(context);
showTopSnackbar(context,
message: context.translate(I18n.remoteListening),
type: MessageType.success);
}
}
},
);
return Container(
padding: SizeUtils.getByScreen(

View File

@@ -64,6 +64,7 @@ class VolumeControlViewModel extends Notifier<VolumeControlViewState> {
);
if (!ref.mounted) return;
ref.syncDeviceSettings(device, updatedSettings);
state = state.copyWith(isLoading: false, isComplete: true);
} catch (e) {
if (!ref.mounted) return;

View File

@@ -24,7 +24,7 @@ class LocationViewModel extends Notifier<LocationViewState> {
@override
LocationViewState build() {
_locationRepository = ref.read(locationRepositoryProvider);
final device = ref.watch(selectedDeviceProvider);
final device = ref.read(selectedDeviceProvider);
if (device != null) {
_fetchData(device.id);
}
@@ -282,6 +282,7 @@ class LocationViewModel extends Notifier<LocationViewState> {
);
if (!ref.mounted) return false;
ref.syncDeviceSettings(device, updatedSettings);
state = state.copyWith(isSubmitting: false);
return true;
} catch (e) {

View File

@@ -566,7 +566,7 @@ class _LocationMapState extends ConsumerState<LocationMap>
const SizedBox(height: 8),
FrequencySelector(
currentFrequency:
widget.selectedDevice!.settings.frequency,
ref.watch(selectedDeviceProvider)?.settings.frequency ?? 60,
options:
widget.selectedDevice!.capabilities!.location!.options,
onChanged: _updateFrequency,

View File

@@ -57,6 +57,7 @@ class AlertsViewModel extends Notifier<AlertsViewState> {
updatedSettings: updatedSettings,
);
if (!ref.mounted) return;
ref.syncDeviceSettings(device, updatedSettings);
state = state.copyWith(isSaving: false, saveSuccess: true);
} catch (e) {
if (!ref.mounted) return;

View File

@@ -41,6 +41,7 @@ class BatteryViewModel extends Notifier<BatteryViewState> {
updatedSettings: updatedSettings,
);
if (!ref.mounted) return;
ref.syncDeviceSettings(device, updatedSettings);
state = state.copyWith(
nightMode: value,
isSaving: false,

View File

@@ -53,6 +53,7 @@ class DisableFunctionsViewModel extends Notifier<DisableFunctionsViewState> {
updatedSettings: updatedSettings,
);
if (!ref.mounted) return;
ref.syncDeviceSettings(device, updatedSettings);
state = state.copyWith(isSaving: false, saveSuccess: true);
} catch (e) {
if (!ref.mounted) return;

View File

@@ -57,6 +57,10 @@ class LanguageViewModel extends Notifier<LanguageViewState> {
);
if (!ref.mounted) return;
ref.syncDeviceSettings(
device,
device.settings.copyWith(language: state.language),
);
state = state.copyWith(isLoading: false, isComplete: true);
} catch (e) {
if (!ref.mounted) return;

View File

@@ -60,6 +60,7 @@ class SoundViewModel extends Notifier<SoundViewState> {
);
if (!ref.mounted) return;
ref.syncDeviceSettings(device, updatedSettings);
state = state.copyWith(isLoading: false, isComplete: true);
} catch (e) {
if (!ref.mounted) return;

View File

@@ -52,6 +52,7 @@ class TimezoneViewModel extends Notifier<TimezoneViewState> {
updatedSettings: updatedSettings,
);
if (!ref.mounted) return;
ref.syncDeviceSettings(device, updatedSettings);
state = state.copyWith(isSaving: false, saveSuccess: true);
} catch (e) {
if (!ref.mounted) return;

View File

@@ -14,7 +14,7 @@ class CommandsRemoteDatasourceImpl implements CommandsRemoteDatasource {
required SendCommandRequestModel request,
}) async {
await safeCall(
() => _repository.post<Map<String, dynamic>>(
() => _repository.post<dynamic>(
'/commands',
body: request.toJson(),
),

View File

@@ -16,3 +16,11 @@ class SelectedDeviceNotifier extends Notifier<DeviceEntity?> {
state = device;
}
}
extension DeviceSettingsSync on Ref {
void syncDeviceSettings(DeviceEntity device, DeviceSettingsEntity settings) {
read(selectedDeviceProvider.notifier).setSelectedDevice(
device.copyWith(settings: settings),
);
}
}

View File

@@ -702,5 +702,9 @@
"errorBatteryNightMode": "Der Nachtmodus konnte nicht aktualisiert werden",
"timezoneUpdated": "Zeitzone aktualisiert",
"errorTimezone": "Die Zeitzone konnte nicht aktualisiert werden",
"timezoneOther": "Andere Zeitzonen"
"timezoneOther": "Andere Zeitzonen",
"takingPhoto": "Foto wird aufgenommen...",
"errorTakePicture": "Fehler beim Fotografieren",
"errorFetchPhotos": "Fehler beim Abrufen der Fotos",
"errorCall": "Fehler beim Anrufen"
}

View File

@@ -833,5 +833,9 @@
"errorBatteryNightMode": "Could not update night mode",
"timezoneUpdated": "Timezone updated",
"errorTimezone": "Could not update timezone",
"timezoneOther": "Other timezones"
"timezoneOther": "Other timezones",
"takingPhoto": "Taking photo...",
"errorTakePicture": "Error taking photo",
"errorFetchPhotos": "Error fetching photos",
"errorCall": "Error making call"
}

View File

@@ -831,5 +831,9 @@
"errorBatteryNightMode": "No se pudo actualizar el modo nocturno",
"timezoneUpdated": "Zona horaria actualizada",
"errorTimezone": "No se pudo actualizar la zona horaria",
"timezoneOther": "Otras zonas horarias"
"timezoneOther": "Otras zonas horarias",
"takingPhoto": "Tomando foto...",
"errorTakePicture": "Error al tomar la foto",
"errorFetchPhotos": "Error al obtener las fotos",
"errorCall": "Error al realizar la llamada"
}

View File

@@ -702,5 +702,9 @@
"errorBatteryNightMode": "Impossible de mettre à jour le mode nuit",
"timezoneUpdated": "Fuseau horaire mis à jour",
"errorTimezone": "Impossible de mettre à jour le fuseau horaire",
"timezoneOther": "Autres fuseaux horaires"
"timezoneOther": "Autres fuseaux horaires",
"takingPhoto": "Prise de photo...",
"errorTakePicture": "Erreur lors de la prise de photo",
"errorFetchPhotos": "Erreur lors de la récupération des photos",
"errorCall": "Erreur lors de l'appel"
}

View File

@@ -702,5 +702,9 @@
"errorBatteryNightMode": "Impossibile aggiornare la modalità notturna",
"timezoneUpdated": "Fuso orario aggiornato",
"errorTimezone": "Impossibile aggiornare il fuso orario",
"timezoneOther": "Altri fusi orari"
"timezoneOther": "Altri fusi orari",
"takingPhoto": "Scattando foto...",
"errorTakePicture": "Errore durante lo scatto della foto",
"errorFetchPhotos": "Errore durante il recupero delle foto",
"errorCall": "Errore durante la chiamata"
}

View File

@@ -702,5 +702,9 @@
"errorBatteryNightMode": "Não foi possível atualizar o modo noturno",
"timezoneUpdated": "Fuso horário atualizado",
"errorTimezone": "Não foi possível atualizar o fuso horário",
"timezoneOther": "Outros fusos horários"
"timezoneOther": "Outros fusos horários",
"takingPhoto": "Tirando foto...",
"errorTakePicture": "Erro ao tirar foto",
"errorFetchPhotos": "Erro ao obter fotos",
"errorCall": "Erro ao realizar chamada"
}

View File

@@ -836,4 +836,8 @@ class I18n {
static const String timezoneUpdated = 'timezoneUpdated';
static const String errorTimezone = 'errorTimezone';
static const String timezoneOther = 'timezoneOther';
static const String takingPhoto = 'takingPhoto';
static const String errorTakePicture = 'errorTakePicture';
static const String errorFetchPhotos = 'errorFetchPhotos';
static const String errorCall = 'errorCall';
}

View File

@@ -18,6 +18,7 @@ abstract class DeviceSettingsModel with _$DeviceSettingsModel {
@Default(true) bool keyboard,
@Default(true) bool gps,
@Default(false) bool nightMode,
String? backgroundImageId,
}) = _DeviceSettingsModel;
factory DeviceSettingsModel.fromJson(Map<String, dynamic> json) =>
@@ -53,6 +54,7 @@ extension DeviceSettingsModelMapper on DeviceSettingsModel {
keyboard: keyboard,
gps: gps,
nightMode: nightMode,
backgroundImageId: backgroundImageId,
);
}

View File

@@ -15,7 +15,7 @@ T _$identity<T>(T value) => value;
/// @nodoc
mixin _$DeviceSettingsModel {
int get frequency; int get frequencyHeartRate; int get timezone; bool get pedometer; String get language; List<String> get alerts; DeviceVolumeModel get volume; String? get soundMode; bool get keyboard; bool get gps; bool get nightMode;
int get frequency; int get frequencyHeartRate; int get timezone; bool get pedometer; String get language; List<String> get alerts; DeviceVolumeModel get volume; String? get soundMode; bool get keyboard; bool get gps; bool get nightMode; String? get backgroundImageId;
/// Create a copy of DeviceSettingsModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -28,16 +28,16 @@ $DeviceSettingsModelCopyWith<DeviceSettingsModel> get copyWith => _$DeviceSettin
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is DeviceSettingsModel&&(identical(other.frequency, frequency) || other.frequency == frequency)&&(identical(other.frequencyHeartRate, frequencyHeartRate) || other.frequencyHeartRate == frequencyHeartRate)&&(identical(other.timezone, timezone) || other.timezone == timezone)&&(identical(other.pedometer, pedometer) || other.pedometer == pedometer)&&(identical(other.language, language) || other.language == language)&&const DeepCollectionEquality().equals(other.alerts, alerts)&&(identical(other.volume, volume) || other.volume == volume)&&(identical(other.soundMode, soundMode) || other.soundMode == soundMode)&&(identical(other.keyboard, keyboard) || other.keyboard == keyboard)&&(identical(other.gps, gps) || other.gps == gps)&&(identical(other.nightMode, nightMode) || other.nightMode == nightMode));
return identical(this, other) || (other.runtimeType == runtimeType&&other is DeviceSettingsModel&&(identical(other.frequency, frequency) || other.frequency == frequency)&&(identical(other.frequencyHeartRate, frequencyHeartRate) || other.frequencyHeartRate == frequencyHeartRate)&&(identical(other.timezone, timezone) || other.timezone == timezone)&&(identical(other.pedometer, pedometer) || other.pedometer == pedometer)&&(identical(other.language, language) || other.language == language)&&const DeepCollectionEquality().equals(other.alerts, alerts)&&(identical(other.volume, volume) || other.volume == volume)&&(identical(other.soundMode, soundMode) || other.soundMode == soundMode)&&(identical(other.keyboard, keyboard) || other.keyboard == keyboard)&&(identical(other.gps, gps) || other.gps == gps)&&(identical(other.nightMode, nightMode) || other.nightMode == nightMode)&&(identical(other.backgroundImageId, backgroundImageId) || other.backgroundImageId == backgroundImageId));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,frequency,frequencyHeartRate,timezone,pedometer,language,const DeepCollectionEquality().hash(alerts),volume,soundMode,keyboard,gps,nightMode);
int get hashCode => Object.hash(runtimeType,frequency,frequencyHeartRate,timezone,pedometer,language,const DeepCollectionEquality().hash(alerts),volume,soundMode,keyboard,gps,nightMode,backgroundImageId);
@override
String toString() {
return 'DeviceSettingsModel(frequency: $frequency, frequencyHeartRate: $frequencyHeartRate, timezone: $timezone, pedometer: $pedometer, language: $language, alerts: $alerts, volume: $volume, soundMode: $soundMode, keyboard: $keyboard, gps: $gps, nightMode: $nightMode)';
return 'DeviceSettingsModel(frequency: $frequency, frequencyHeartRate: $frequencyHeartRate, timezone: $timezone, pedometer: $pedometer, language: $language, alerts: $alerts, volume: $volume, soundMode: $soundMode, keyboard: $keyboard, gps: $gps, nightMode: $nightMode, backgroundImageId: $backgroundImageId)';
}
@@ -48,7 +48,7 @@ abstract mixin class $DeviceSettingsModelCopyWith<$Res> {
factory $DeviceSettingsModelCopyWith(DeviceSettingsModel value, $Res Function(DeviceSettingsModel) _then) = _$DeviceSettingsModelCopyWithImpl;
@useResult
$Res call({
int frequency, int frequencyHeartRate, int timezone, bool pedometer, String language, List<String> alerts, DeviceVolumeModel volume, String? soundMode, bool keyboard, bool gps, bool nightMode
int frequency, int frequencyHeartRate, int timezone, bool pedometer, String language, List<String> alerts, DeviceVolumeModel volume, String? soundMode, bool keyboard, bool gps, bool nightMode, String? backgroundImageId
});
@@ -65,7 +65,7 @@ class _$DeviceSettingsModelCopyWithImpl<$Res>
/// Create a copy of DeviceSettingsModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? frequency = null,Object? frequencyHeartRate = null,Object? timezone = null,Object? pedometer = null,Object? language = null,Object? alerts = null,Object? volume = null,Object? soundMode = freezed,Object? keyboard = null,Object? gps = null,Object? nightMode = null,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? frequency = null,Object? frequencyHeartRate = null,Object? timezone = null,Object? pedometer = null,Object? language = null,Object? alerts = null,Object? volume = null,Object? soundMode = freezed,Object? keyboard = null,Object? gps = null,Object? nightMode = null,Object? backgroundImageId = freezed,}) {
return _then(_self.copyWith(
frequency: null == frequency ? _self.frequency : frequency // ignore: cast_nullable_to_non_nullable
as int,frequencyHeartRate: null == frequencyHeartRate ? _self.frequencyHeartRate : frequencyHeartRate // ignore: cast_nullable_to_non_nullable
@@ -78,7 +78,8 @@ as DeviceVolumeModel,soundMode: freezed == soundMode ? _self.soundMode : soundMo
as String?,keyboard: null == keyboard ? _self.keyboard : keyboard // ignore: cast_nullable_to_non_nullable
as bool,gps: null == gps ? _self.gps : gps // ignore: cast_nullable_to_non_nullable
as bool,nightMode: null == nightMode ? _self.nightMode : nightMode // ignore: cast_nullable_to_non_nullable
as bool,
as bool,backgroundImageId: freezed == backgroundImageId ? _self.backgroundImageId : backgroundImageId // ignore: cast_nullable_to_non_nullable
as String?,
));
}
/// Create a copy of DeviceSettingsModel
@@ -172,10 +173,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( int frequency, int frequencyHeartRate, int timezone, bool pedometer, String language, List<String> alerts, DeviceVolumeModel volume, String? soundMode, bool keyboard, bool gps, bool nightMode)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( int frequency, int frequencyHeartRate, int timezone, bool pedometer, String language, List<String> alerts, DeviceVolumeModel volume, String? soundMode, bool keyboard, bool gps, bool nightMode, String? backgroundImageId)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _DeviceSettingsModel() when $default != null:
return $default(_that.frequency,_that.frequencyHeartRate,_that.timezone,_that.pedometer,_that.language,_that.alerts,_that.volume,_that.soundMode,_that.keyboard,_that.gps,_that.nightMode);case _:
return $default(_that.frequency,_that.frequencyHeartRate,_that.timezone,_that.pedometer,_that.language,_that.alerts,_that.volume,_that.soundMode,_that.keyboard,_that.gps,_that.nightMode,_that.backgroundImageId);case _:
return orElse();
}
@@ -193,10 +194,10 @@ return $default(_that.frequency,_that.frequencyHeartRate,_that.timezone,_that.pe
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( int frequency, int frequencyHeartRate, int timezone, bool pedometer, String language, List<String> alerts, DeviceVolumeModel volume, String? soundMode, bool keyboard, bool gps, bool nightMode) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( int frequency, int frequencyHeartRate, int timezone, bool pedometer, String language, List<String> alerts, DeviceVolumeModel volume, String? soundMode, bool keyboard, bool gps, bool nightMode, String? backgroundImageId) $default,) {final _that = this;
switch (_that) {
case _DeviceSettingsModel():
return $default(_that.frequency,_that.frequencyHeartRate,_that.timezone,_that.pedometer,_that.language,_that.alerts,_that.volume,_that.soundMode,_that.keyboard,_that.gps,_that.nightMode);case _:
return $default(_that.frequency,_that.frequencyHeartRate,_that.timezone,_that.pedometer,_that.language,_that.alerts,_that.volume,_that.soundMode,_that.keyboard,_that.gps,_that.nightMode,_that.backgroundImageId);case _:
throw StateError('Unexpected subclass');
}
@@ -213,10 +214,10 @@ return $default(_that.frequency,_that.frequencyHeartRate,_that.timezone,_that.pe
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( int frequency, int frequencyHeartRate, int timezone, bool pedometer, String language, List<String> alerts, DeviceVolumeModel volume, String? soundMode, bool keyboard, bool gps, bool nightMode)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( int frequency, int frequencyHeartRate, int timezone, bool pedometer, String language, List<String> alerts, DeviceVolumeModel volume, String? soundMode, bool keyboard, bool gps, bool nightMode, String? backgroundImageId)? $default,) {final _that = this;
switch (_that) {
case _DeviceSettingsModel() when $default != null:
return $default(_that.frequency,_that.frequencyHeartRate,_that.timezone,_that.pedometer,_that.language,_that.alerts,_that.volume,_that.soundMode,_that.keyboard,_that.gps,_that.nightMode);case _:
return $default(_that.frequency,_that.frequencyHeartRate,_that.timezone,_that.pedometer,_that.language,_that.alerts,_that.volume,_that.soundMode,_that.keyboard,_that.gps,_that.nightMode,_that.backgroundImageId);case _:
return null;
}
@@ -228,7 +229,7 @@ return $default(_that.frequency,_that.frequencyHeartRate,_that.timezone,_that.pe
@JsonSerializable()
class _DeviceSettingsModel implements DeviceSettingsModel {
const _DeviceSettingsModel({this.frequency = 60, this.frequencyHeartRate = 120, this.timezone = 0, this.pedometer = false, this.language = 'es', final List<String> alerts = const [], this.volume = const DeviceVolumeModel(), this.soundMode, this.keyboard = true, this.gps = true, this.nightMode = false}): _alerts = alerts;
const _DeviceSettingsModel({this.frequency = 60, this.frequencyHeartRate = 120, this.timezone = 0, this.pedometer = false, this.language = 'es', final List<String> alerts = const [], this.volume = const DeviceVolumeModel(), this.soundMode, this.keyboard = true, this.gps = true, this.nightMode = false, this.backgroundImageId}): _alerts = alerts;
factory _DeviceSettingsModel.fromJson(Map<String, dynamic> json) => _$DeviceSettingsModelFromJson(json);
@override@JsonKey() final int frequency;
@@ -248,6 +249,7 @@ class _DeviceSettingsModel implements DeviceSettingsModel {
@override@JsonKey() final bool keyboard;
@override@JsonKey() final bool gps;
@override@JsonKey() final bool nightMode;
@override final String? backgroundImageId;
/// Create a copy of DeviceSettingsModel
/// with the given fields replaced by the non-null parameter values.
@@ -262,16 +264,16 @@ Map<String, dynamic> toJson() {
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _DeviceSettingsModel&&(identical(other.frequency, frequency) || other.frequency == frequency)&&(identical(other.frequencyHeartRate, frequencyHeartRate) || other.frequencyHeartRate == frequencyHeartRate)&&(identical(other.timezone, timezone) || other.timezone == timezone)&&(identical(other.pedometer, pedometer) || other.pedometer == pedometer)&&(identical(other.language, language) || other.language == language)&&const DeepCollectionEquality().equals(other._alerts, _alerts)&&(identical(other.volume, volume) || other.volume == volume)&&(identical(other.soundMode, soundMode) || other.soundMode == soundMode)&&(identical(other.keyboard, keyboard) || other.keyboard == keyboard)&&(identical(other.gps, gps) || other.gps == gps)&&(identical(other.nightMode, nightMode) || other.nightMode == nightMode));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _DeviceSettingsModel&&(identical(other.frequency, frequency) || other.frequency == frequency)&&(identical(other.frequencyHeartRate, frequencyHeartRate) || other.frequencyHeartRate == frequencyHeartRate)&&(identical(other.timezone, timezone) || other.timezone == timezone)&&(identical(other.pedometer, pedometer) || other.pedometer == pedometer)&&(identical(other.language, language) || other.language == language)&&const DeepCollectionEquality().equals(other._alerts, _alerts)&&(identical(other.volume, volume) || other.volume == volume)&&(identical(other.soundMode, soundMode) || other.soundMode == soundMode)&&(identical(other.keyboard, keyboard) || other.keyboard == keyboard)&&(identical(other.gps, gps) || other.gps == gps)&&(identical(other.nightMode, nightMode) || other.nightMode == nightMode)&&(identical(other.backgroundImageId, backgroundImageId) || other.backgroundImageId == backgroundImageId));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,frequency,frequencyHeartRate,timezone,pedometer,language,const DeepCollectionEquality().hash(_alerts),volume,soundMode,keyboard,gps,nightMode);
int get hashCode => Object.hash(runtimeType,frequency,frequencyHeartRate,timezone,pedometer,language,const DeepCollectionEquality().hash(_alerts),volume,soundMode,keyboard,gps,nightMode,backgroundImageId);
@override
String toString() {
return 'DeviceSettingsModel(frequency: $frequency, frequencyHeartRate: $frequencyHeartRate, timezone: $timezone, pedometer: $pedometer, language: $language, alerts: $alerts, volume: $volume, soundMode: $soundMode, keyboard: $keyboard, gps: $gps, nightMode: $nightMode)';
return 'DeviceSettingsModel(frequency: $frequency, frequencyHeartRate: $frequencyHeartRate, timezone: $timezone, pedometer: $pedometer, language: $language, alerts: $alerts, volume: $volume, soundMode: $soundMode, keyboard: $keyboard, gps: $gps, nightMode: $nightMode, backgroundImageId: $backgroundImageId)';
}
@@ -282,7 +284,7 @@ abstract mixin class _$DeviceSettingsModelCopyWith<$Res> implements $DeviceSetti
factory _$DeviceSettingsModelCopyWith(_DeviceSettingsModel value, $Res Function(_DeviceSettingsModel) _then) = __$DeviceSettingsModelCopyWithImpl;
@override @useResult
$Res call({
int frequency, int frequencyHeartRate, int timezone, bool pedometer, String language, List<String> alerts, DeviceVolumeModel volume, String? soundMode, bool keyboard, bool gps, bool nightMode
int frequency, int frequencyHeartRate, int timezone, bool pedometer, String language, List<String> alerts, DeviceVolumeModel volume, String? soundMode, bool keyboard, bool gps, bool nightMode, String? backgroundImageId
});
@@ -299,7 +301,7 @@ class __$DeviceSettingsModelCopyWithImpl<$Res>
/// Create a copy of DeviceSettingsModel
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? frequency = null,Object? frequencyHeartRate = null,Object? timezone = null,Object? pedometer = null,Object? language = null,Object? alerts = null,Object? volume = null,Object? soundMode = freezed,Object? keyboard = null,Object? gps = null,Object? nightMode = null,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? frequency = null,Object? frequencyHeartRate = null,Object? timezone = null,Object? pedometer = null,Object? language = null,Object? alerts = null,Object? volume = null,Object? soundMode = freezed,Object? keyboard = null,Object? gps = null,Object? nightMode = null,Object? backgroundImageId = freezed,}) {
return _then(_DeviceSettingsModel(
frequency: null == frequency ? _self.frequency : frequency // ignore: cast_nullable_to_non_nullable
as int,frequencyHeartRate: null == frequencyHeartRate ? _self.frequencyHeartRate : frequencyHeartRate // ignore: cast_nullable_to_non_nullable
@@ -312,7 +314,8 @@ as DeviceVolumeModel,soundMode: freezed == soundMode ? _self.soundMode : soundMo
as String?,keyboard: null == keyboard ? _self.keyboard : keyboard // ignore: cast_nullable_to_non_nullable
as bool,gps: null == gps ? _self.gps : gps // ignore: cast_nullable_to_non_nullable
as bool,nightMode: null == nightMode ? _self.nightMode : nightMode // ignore: cast_nullable_to_non_nullable
as bool,
as bool,backgroundImageId: freezed == backgroundImageId ? _self.backgroundImageId : backgroundImageId // ignore: cast_nullable_to_non_nullable
as String?,
));
}

View File

@@ -25,6 +25,7 @@ _DeviceSettingsModel _$DeviceSettingsModelFromJson(Map<String, dynamic> json) =>
keyboard: json['keyboard'] as bool? ?? true,
gps: json['gps'] as bool? ?? true,
nightMode: json['nightMode'] as bool? ?? false,
backgroundImageId: json['backgroundImageId'] as String?,
);
Map<String, dynamic> _$DeviceSettingsModelToJson(
@@ -41,6 +42,7 @@ Map<String, dynamic> _$DeviceSettingsModelToJson(
'keyboard': instance.keyboard,
'gps': instance.gps,
'nightMode': instance.nightMode,
'backgroundImageId': instance.backgroundImageId,
};
_DeviceVolumeModel _$DeviceVolumeModelFromJson(Map<String, dynamic> json) =>

View File

@@ -16,6 +16,7 @@ abstract class DeviceSettingsEntity with _$DeviceSettingsEntity {
@Default(true) bool keyboard,
@Default(true) bool gps,
@Default(false) bool nightMode,
String? backgroundImageId,
}) = _DeviceSettingsEntity;
}

View File

@@ -14,7 +14,7 @@ T _$identity<T>(T value) => value;
/// @nodoc
mixin _$DeviceSettingsEntity {
int get frequency; int get frequencyHeartRate; int get timezone; bool get pedometer; String get language; List<String> get alerts; DeviceVolumeEntity get volume; String? get soundMode; bool get keyboard; bool get gps; bool get nightMode;
int get frequency; int get frequencyHeartRate; int get timezone; bool get pedometer; String get language; List<String> get alerts; DeviceVolumeEntity get volume; String? get soundMode; bool get keyboard; bool get gps; bool get nightMode; String? get backgroundImageId;
/// Create a copy of DeviceSettingsEntity
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -25,16 +25,16 @@ $DeviceSettingsEntityCopyWith<DeviceSettingsEntity> get copyWith => _$DeviceSett
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is DeviceSettingsEntity&&(identical(other.frequency, frequency) || other.frequency == frequency)&&(identical(other.frequencyHeartRate, frequencyHeartRate) || other.frequencyHeartRate == frequencyHeartRate)&&(identical(other.timezone, timezone) || other.timezone == timezone)&&(identical(other.pedometer, pedometer) || other.pedometer == pedometer)&&(identical(other.language, language) || other.language == language)&&const DeepCollectionEquality().equals(other.alerts, alerts)&&(identical(other.volume, volume) || other.volume == volume)&&(identical(other.soundMode, soundMode) || other.soundMode == soundMode)&&(identical(other.keyboard, keyboard) || other.keyboard == keyboard)&&(identical(other.gps, gps) || other.gps == gps)&&(identical(other.nightMode, nightMode) || other.nightMode == nightMode));
return identical(this, other) || (other.runtimeType == runtimeType&&other is DeviceSettingsEntity&&(identical(other.frequency, frequency) || other.frequency == frequency)&&(identical(other.frequencyHeartRate, frequencyHeartRate) || other.frequencyHeartRate == frequencyHeartRate)&&(identical(other.timezone, timezone) || other.timezone == timezone)&&(identical(other.pedometer, pedometer) || other.pedometer == pedometer)&&(identical(other.language, language) || other.language == language)&&const DeepCollectionEquality().equals(other.alerts, alerts)&&(identical(other.volume, volume) || other.volume == volume)&&(identical(other.soundMode, soundMode) || other.soundMode == soundMode)&&(identical(other.keyboard, keyboard) || other.keyboard == keyboard)&&(identical(other.gps, gps) || other.gps == gps)&&(identical(other.nightMode, nightMode) || other.nightMode == nightMode)&&(identical(other.backgroundImageId, backgroundImageId) || other.backgroundImageId == backgroundImageId));
}
@override
int get hashCode => Object.hash(runtimeType,frequency,frequencyHeartRate,timezone,pedometer,language,const DeepCollectionEquality().hash(alerts),volume,soundMode,keyboard,gps,nightMode);
int get hashCode => Object.hash(runtimeType,frequency,frequencyHeartRate,timezone,pedometer,language,const DeepCollectionEquality().hash(alerts),volume,soundMode,keyboard,gps,nightMode,backgroundImageId);
@override
String toString() {
return 'DeviceSettingsEntity(frequency: $frequency, frequencyHeartRate: $frequencyHeartRate, timezone: $timezone, pedometer: $pedometer, language: $language, alerts: $alerts, volume: $volume, soundMode: $soundMode, keyboard: $keyboard, gps: $gps, nightMode: $nightMode)';
return 'DeviceSettingsEntity(frequency: $frequency, frequencyHeartRate: $frequencyHeartRate, timezone: $timezone, pedometer: $pedometer, language: $language, alerts: $alerts, volume: $volume, soundMode: $soundMode, keyboard: $keyboard, gps: $gps, nightMode: $nightMode, backgroundImageId: $backgroundImageId)';
}
@@ -45,7 +45,7 @@ abstract mixin class $DeviceSettingsEntityCopyWith<$Res> {
factory $DeviceSettingsEntityCopyWith(DeviceSettingsEntity value, $Res Function(DeviceSettingsEntity) _then) = _$DeviceSettingsEntityCopyWithImpl;
@useResult
$Res call({
int frequency, int frequencyHeartRate, int timezone, bool pedometer, String language, List<String> alerts, DeviceVolumeEntity volume, String? soundMode, bool keyboard, bool gps, bool nightMode
int frequency, int frequencyHeartRate, int timezone, bool pedometer, String language, List<String> alerts, DeviceVolumeEntity volume, String? soundMode, bool keyboard, bool gps, bool nightMode, String? backgroundImageId
});
@@ -62,7 +62,7 @@ class _$DeviceSettingsEntityCopyWithImpl<$Res>
/// Create a copy of DeviceSettingsEntity
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? frequency = null,Object? frequencyHeartRate = null,Object? timezone = null,Object? pedometer = null,Object? language = null,Object? alerts = null,Object? volume = null,Object? soundMode = freezed,Object? keyboard = null,Object? gps = null,Object? nightMode = null,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? frequency = null,Object? frequencyHeartRate = null,Object? timezone = null,Object? pedometer = null,Object? language = null,Object? alerts = null,Object? volume = null,Object? soundMode = freezed,Object? keyboard = null,Object? gps = null,Object? nightMode = null,Object? backgroundImageId = freezed,}) {
return _then(_self.copyWith(
frequency: null == frequency ? _self.frequency : frequency // ignore: cast_nullable_to_non_nullable
as int,frequencyHeartRate: null == frequencyHeartRate ? _self.frequencyHeartRate : frequencyHeartRate // ignore: cast_nullable_to_non_nullable
@@ -75,7 +75,8 @@ as DeviceVolumeEntity,soundMode: freezed == soundMode ? _self.soundMode : soundM
as String?,keyboard: null == keyboard ? _self.keyboard : keyboard // ignore: cast_nullable_to_non_nullable
as bool,gps: null == gps ? _self.gps : gps // ignore: cast_nullable_to_non_nullable
as bool,nightMode: null == nightMode ? _self.nightMode : nightMode // ignore: cast_nullable_to_non_nullable
as bool,
as bool,backgroundImageId: freezed == backgroundImageId ? _self.backgroundImageId : backgroundImageId // ignore: cast_nullable_to_non_nullable
as String?,
));
}
/// Create a copy of DeviceSettingsEntity
@@ -169,10 +170,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( int frequency, int frequencyHeartRate, int timezone, bool pedometer, String language, List<String> alerts, DeviceVolumeEntity volume, String? soundMode, bool keyboard, bool gps, bool nightMode)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( int frequency, int frequencyHeartRate, int timezone, bool pedometer, String language, List<String> alerts, DeviceVolumeEntity volume, String? soundMode, bool keyboard, bool gps, bool nightMode, String? backgroundImageId)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _DeviceSettingsEntity() when $default != null:
return $default(_that.frequency,_that.frequencyHeartRate,_that.timezone,_that.pedometer,_that.language,_that.alerts,_that.volume,_that.soundMode,_that.keyboard,_that.gps,_that.nightMode);case _:
return $default(_that.frequency,_that.frequencyHeartRate,_that.timezone,_that.pedometer,_that.language,_that.alerts,_that.volume,_that.soundMode,_that.keyboard,_that.gps,_that.nightMode,_that.backgroundImageId);case _:
return orElse();
}
@@ -190,10 +191,10 @@ return $default(_that.frequency,_that.frequencyHeartRate,_that.timezone,_that.pe
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( int frequency, int frequencyHeartRate, int timezone, bool pedometer, String language, List<String> alerts, DeviceVolumeEntity volume, String? soundMode, bool keyboard, bool gps, bool nightMode) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( int frequency, int frequencyHeartRate, int timezone, bool pedometer, String language, List<String> alerts, DeviceVolumeEntity volume, String? soundMode, bool keyboard, bool gps, bool nightMode, String? backgroundImageId) $default,) {final _that = this;
switch (_that) {
case _DeviceSettingsEntity():
return $default(_that.frequency,_that.frequencyHeartRate,_that.timezone,_that.pedometer,_that.language,_that.alerts,_that.volume,_that.soundMode,_that.keyboard,_that.gps,_that.nightMode);case _:
return $default(_that.frequency,_that.frequencyHeartRate,_that.timezone,_that.pedometer,_that.language,_that.alerts,_that.volume,_that.soundMode,_that.keyboard,_that.gps,_that.nightMode,_that.backgroundImageId);case _:
throw StateError('Unexpected subclass');
}
@@ -210,10 +211,10 @@ return $default(_that.frequency,_that.frequencyHeartRate,_that.timezone,_that.pe
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( int frequency, int frequencyHeartRate, int timezone, bool pedometer, String language, List<String> alerts, DeviceVolumeEntity volume, String? soundMode, bool keyboard, bool gps, bool nightMode)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( int frequency, int frequencyHeartRate, int timezone, bool pedometer, String language, List<String> alerts, DeviceVolumeEntity volume, String? soundMode, bool keyboard, bool gps, bool nightMode, String? backgroundImageId)? $default,) {final _that = this;
switch (_that) {
case _DeviceSettingsEntity() when $default != null:
return $default(_that.frequency,_that.frequencyHeartRate,_that.timezone,_that.pedometer,_that.language,_that.alerts,_that.volume,_that.soundMode,_that.keyboard,_that.gps,_that.nightMode);case _:
return $default(_that.frequency,_that.frequencyHeartRate,_that.timezone,_that.pedometer,_that.language,_that.alerts,_that.volume,_that.soundMode,_that.keyboard,_that.gps,_that.nightMode,_that.backgroundImageId);case _:
return null;
}
@@ -225,7 +226,7 @@ return $default(_that.frequency,_that.frequencyHeartRate,_that.timezone,_that.pe
class _DeviceSettingsEntity implements DeviceSettingsEntity {
const _DeviceSettingsEntity({this.frequency = 60, this.frequencyHeartRate = 120, this.timezone = 0, this.pedometer = false, this.language = 'es', final List<String> alerts = const [], this.volume = const DeviceVolumeEntity(), this.soundMode, this.keyboard = true, this.gps = true, this.nightMode = false}): _alerts = alerts;
const _DeviceSettingsEntity({this.frequency = 60, this.frequencyHeartRate = 120, this.timezone = 0, this.pedometer = false, this.language = 'es', final List<String> alerts = const [], this.volume = const DeviceVolumeEntity(), this.soundMode, this.keyboard = true, this.gps = true, this.nightMode = false, this.backgroundImageId}): _alerts = alerts;
@override@JsonKey() final int frequency;
@@ -245,6 +246,7 @@ class _DeviceSettingsEntity implements DeviceSettingsEntity {
@override@JsonKey() final bool keyboard;
@override@JsonKey() final bool gps;
@override@JsonKey() final bool nightMode;
@override final String? backgroundImageId;
/// Create a copy of DeviceSettingsEntity
/// with the given fields replaced by the non-null parameter values.
@@ -256,16 +258,16 @@ _$DeviceSettingsEntityCopyWith<_DeviceSettingsEntity> get copyWith => __$DeviceS
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _DeviceSettingsEntity&&(identical(other.frequency, frequency) || other.frequency == frequency)&&(identical(other.frequencyHeartRate, frequencyHeartRate) || other.frequencyHeartRate == frequencyHeartRate)&&(identical(other.timezone, timezone) || other.timezone == timezone)&&(identical(other.pedometer, pedometer) || other.pedometer == pedometer)&&(identical(other.language, language) || other.language == language)&&const DeepCollectionEquality().equals(other._alerts, _alerts)&&(identical(other.volume, volume) || other.volume == volume)&&(identical(other.soundMode, soundMode) || other.soundMode == soundMode)&&(identical(other.keyboard, keyboard) || other.keyboard == keyboard)&&(identical(other.gps, gps) || other.gps == gps)&&(identical(other.nightMode, nightMode) || other.nightMode == nightMode));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _DeviceSettingsEntity&&(identical(other.frequency, frequency) || other.frequency == frequency)&&(identical(other.frequencyHeartRate, frequencyHeartRate) || other.frequencyHeartRate == frequencyHeartRate)&&(identical(other.timezone, timezone) || other.timezone == timezone)&&(identical(other.pedometer, pedometer) || other.pedometer == pedometer)&&(identical(other.language, language) || other.language == language)&&const DeepCollectionEquality().equals(other._alerts, _alerts)&&(identical(other.volume, volume) || other.volume == volume)&&(identical(other.soundMode, soundMode) || other.soundMode == soundMode)&&(identical(other.keyboard, keyboard) || other.keyboard == keyboard)&&(identical(other.gps, gps) || other.gps == gps)&&(identical(other.nightMode, nightMode) || other.nightMode == nightMode)&&(identical(other.backgroundImageId, backgroundImageId) || other.backgroundImageId == backgroundImageId));
}
@override
int get hashCode => Object.hash(runtimeType,frequency,frequencyHeartRate,timezone,pedometer,language,const DeepCollectionEquality().hash(_alerts),volume,soundMode,keyboard,gps,nightMode);
int get hashCode => Object.hash(runtimeType,frequency,frequencyHeartRate,timezone,pedometer,language,const DeepCollectionEquality().hash(_alerts),volume,soundMode,keyboard,gps,nightMode,backgroundImageId);
@override
String toString() {
return 'DeviceSettingsEntity(frequency: $frequency, frequencyHeartRate: $frequencyHeartRate, timezone: $timezone, pedometer: $pedometer, language: $language, alerts: $alerts, volume: $volume, soundMode: $soundMode, keyboard: $keyboard, gps: $gps, nightMode: $nightMode)';
return 'DeviceSettingsEntity(frequency: $frequency, frequencyHeartRate: $frequencyHeartRate, timezone: $timezone, pedometer: $pedometer, language: $language, alerts: $alerts, volume: $volume, soundMode: $soundMode, keyboard: $keyboard, gps: $gps, nightMode: $nightMode, backgroundImageId: $backgroundImageId)';
}
@@ -276,7 +278,7 @@ abstract mixin class _$DeviceSettingsEntityCopyWith<$Res> implements $DeviceSett
factory _$DeviceSettingsEntityCopyWith(_DeviceSettingsEntity value, $Res Function(_DeviceSettingsEntity) _then) = __$DeviceSettingsEntityCopyWithImpl;
@override @useResult
$Res call({
int frequency, int frequencyHeartRate, int timezone, bool pedometer, String language, List<String> alerts, DeviceVolumeEntity volume, String? soundMode, bool keyboard, bool gps, bool nightMode
int frequency, int frequencyHeartRate, int timezone, bool pedometer, String language, List<String> alerts, DeviceVolumeEntity volume, String? soundMode, bool keyboard, bool gps, bool nightMode, String? backgroundImageId
});
@@ -293,7 +295,7 @@ class __$DeviceSettingsEntityCopyWithImpl<$Res>
/// Create a copy of DeviceSettingsEntity
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? frequency = null,Object? frequencyHeartRate = null,Object? timezone = null,Object? pedometer = null,Object? language = null,Object? alerts = null,Object? volume = null,Object? soundMode = freezed,Object? keyboard = null,Object? gps = null,Object? nightMode = null,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? frequency = null,Object? frequencyHeartRate = null,Object? timezone = null,Object? pedometer = null,Object? language = null,Object? alerts = null,Object? volume = null,Object? soundMode = freezed,Object? keyboard = null,Object? gps = null,Object? nightMode = null,Object? backgroundImageId = freezed,}) {
return _then(_DeviceSettingsEntity(
frequency: null == frequency ? _self.frequency : frequency // ignore: cast_nullable_to_non_nullable
as int,frequencyHeartRate: null == frequencyHeartRate ? _self.frequencyHeartRate : frequencyHeartRate // ignore: cast_nullable_to_non_nullable
@@ -306,7 +308,8 @@ as DeviceVolumeEntity,soundMode: freezed == soundMode ? _self.soundMode : soundM
as String?,keyboard: null == keyboard ? _self.keyboard : keyboard // ignore: cast_nullable_to_non_nullable
as bool,gps: null == gps ? _self.gps : gps // ignore: cast_nullable_to_non_nullable
as bool,nightMode: null == nightMode ? _self.nightMode : nightMode // ignore: cast_nullable_to_non_nullable
as bool,
as bool,backgroundImageId: freezed == backgroundImageId ? _self.backgroundImageId : backgroundImageId // ignore: cast_nullable_to_non_nullable
as String?,
));
}